Создание DSL на языке Haskell

Aug 30, 2009 03:50

По мотивам поста на Хабрахабре от скуки написал такую же штуку на Haskell'е. Просто, чтобы сравнить.
Я, правда, самой главной функции не написал, но подозреваю, что она на .Net завязана (если даже не на код автора), а разбираться мне было лень, да и суть статьи была в DSL.


data Project = Project String [Resource] UTCTime [Group] deriving (Read, Show)
data Resource = Resource String String Int deriving (Read, Show)
data Group = Group String Resource [Task] deriving (Read, Show)
data Task = Task String String deriving (Read, Show)

resources = accessor (\(Project _ r _ _) -> r) (\r (Project s _ t g) -> Project s r t g)
groups = accessor (\(Project _ _ _ g) -> g) (\g (Project s r t _) -> Project s r t g)
tasks = accessor (\(Group _ _ t) -> t) (\t (Group s r _) -> Group s r t)
headA = accessor head (\v -> (v:).tail)
resourceName (Resource name _ _) = name

project name _ start = put (Project name [] (getTime start) [])
resource name _ position _ rate = modify $ resources ^: (Resource name position rate :)
group name _ resource = modify $ \r -> (groups ^: (Group name (res r) [] :)) r where
    res r = fromMaybe (error $ "Group \"" ++ name ++ "\": no resource with name \"" ++ resource ++ "\" found!") $
        find ((resource == ) . resourceName) (r ^. resources)
task name _ count time = modify $ groups ^: headA ^: tasks ^: (Task name format :) where
    format = show count ++ case time of
        Hour -> "h"
        Day -> "d"
        Week -> "wk"
        Month -> "mon"

-- time
getTime =
    (uncurry mplus) . (parseWith "%d/%m/%Y" &&& parseWith "%d/%m/%y") >>>
    fromMaybe (error "Invalid time format") where
        parseWith = parseTime defaultTimeLocale

-- keywords
starts = ()
isa = ()
rate = ()
done_by = ()
takes = ()

-- duration
data Duration = Hour | Day | Week | Month
hours = Hour
hour = Hour
days = Day
day = Day
weeks = Week
week = Week
months = Month
month = Month

makeProject = flip execState (Project "" [] (error "Time not set") [])

test = makeProject $ do
    project "F# DSL Article" starts "01/01/2009"
    resource "Dmitri" isa "Writer" rate 140
    resource "Computer" isa "Dumb Machine" rate 0
    group "DSL Popularization" done_by "Dmitri"
    task "Create basic estimation DSL" takes 1 day
    task "Write article" takes 1 day
    task "Post article and wait for comments" takes 1 week
    group "Infrastructure Support" done_by "Computer"
    task "Provide VS2010 and MS Project" takes 1 day
    task "Download and deploy TypograFix" takes 1 day
    task "Sit idly while owner waits for comments" takes 1 week

haskell

Previous post Next post
Up