По мотивам
поста на Хабрахабре от скуки написал такую же штуку на 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