Andy Melnikov (nponeccop) wrote,
Andy Melnikov
nponeccop

Category:

Приступаю к изучению чисто функционального языка Clean

Руководствуясь аргументами ниже, я решил переписать свою суперсистему с С++ на Клин.
  • Си и C++  умирают
  • "простые" мейнстримовые языки, на мой взгляд, еще хуже
  • а в вычислительных задачах (конкретно - в тесте N Bodies из Programming Languages Shootout) Clean показывает лучшую производительность, чем не самые последние компиляторы GCC (С++) и GHC (Haskell) я
Для начала, конечно, тестовый кусок, который буду использовать для изучения клина и сравнения получаемой производительности.

Буду писать на клине функцию проверки и автокоррекции поля "дата" для вызова из сишного кода. Сигнатура простая:

String -> Maybe String

Функция проверяет, является ли строка датой в одном из 45 форматов (есть соответствующее количество тестовых случаев) и если является - то приводит дату к формату "Jan 30 2007 18:12:22"

Так как String в клине - unboxed array of Char, я решил пока временно использовать "обычный" список Char - а именно [Char] вместо String, ибо, как известно, функциональные языки предпочитают списки другим типам коллекций.

Вот версия 1:
module acker

import StdEnv, StdMaybe

SplitFirst str sep = takeWhile (not o (flip isMember) sep) str

validate3 f cond d 
    | cond = f d
    | otherwise = Nothing

validate = validate3 Just
validate2 = validate3 (\x = x)

charToInt:: Char -> Maybe Int
charToInt c = validate (c >= '0' && c <= '9') d
where 
    d = (toInt c) - (toInt '0')

// надо перереализовать с использованием функции liftM
// которая отсутствует в скудном рантайме клина (ее тоже реализовать)
metaValidate metaOp op maybeI i = metaOp (isJust maybeI) (op (fromJust maybeI) i)

MaybeOp  = metaValidate validate
MaybeOp2 = metaValidate validate2

// Внутренняя функция, используемая myToInt2. Преобразовывает число в строку 
// за один проход, аккумулируя состояние в первом аргументе.
// Функции, возвращаемые метафункциями MaybeOp и MaybeOp2 служат для 
// продвижения Nothing наверх
myToInt:: Int [Char] -> Maybe Int
myToInt _ [] = Nothing
myToInt oldHd [hd:tl]
    | tl == [] = accum
    | otherwise = MaybeOp2 (myToInt) accum tl
where
    accum::Maybe Int
    accum = MaybeOp (+) i (oldHd * 10)
    i::Maybe Int
    i = charToInt hd

// преобразовывает строку в число
myToInt2 = myToInt 0

Start = myToInt2 (SplitFirst ['7991/01/2003'] ['/'])


С нетерпением жду комментариев и порта на Хаскель.
Tags: compiler design
Subscribe

  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 4 comments