Pull to refresh

GTD DSL на Haskell

Reading time 2 min
Views 1.4K
Давеча искал я программное обеспечение для GTD, или по-русски «как привести дела в порядок». Конечно, многие инструменты красивые и простые, но у таких не хватает гибкости и возможностей настройки. Другие же — сложные монстры с горой ненужной функциональности. Как же совместить безграничную гибкость с простотой?

Я, как любитель текстовых интерфейсов, предпочёл предметно-ориентированный DSL язык вместо GUI. Но писать парсер языка с нуля далеко не просто. Гораздо приятнее надстроить типы над готовым языком Haskell.



data Статус
    = НеСделано
    | Делается
    | Сделано

data Месяца
    = Января
    | Февраля
    | Марта
    | Апреля
    | Мая
    | Июня
    | Июля
    | Августа
    | Сентября
    | Октября
    | Ноября
    | Декабря

data Дата = Дата Integer Месяца Integer

data Когда
    = КогдаНибудь
    | С Дата
    | По Дата
    | Между Дата Дата
    | Возраст Integer

data Куда
    = НаРаботу
    | Домой
    | КЗаказчику
    | НаКурорт
    | ВМагазин

data Кого
    = Сына
    | Дочь
    | Детей Integer

data НаКом
    = Неизвестно
    | Вера
    | Катя
    | Маша

data Что
    = Дерево
    | Дом
    | Печень
    | Предприятие
    | Завод
    | Школу
    | ДетскийСад
    | Университет
    | Клад

data КакойДокумент
    = Контракт
    | Завещание
    | Договор
    | Диплом

data Праздник
    = НовыйГод
    | ДеньРождения

data ЧтоСделать
    = Родиться
    | Умереть
    | Жениться НаКом
    | Родить Кого
    | Посадить Что
    | Построить Что
    | Окончить Что
    | Найти Что
    | Организовать Что
    | Купить Что
    | Продать Что
    | Подписать КакойДокумент
    | Заработать Integer
    | Праздновать Праздник
    
    | Сходить Куда
    | Съездить Куда
    | Слетать Куда
    | Сплавать Куда

data Проект
    = Проект String [Проект]
    | Действие ЧтоСделать Когда Статус

жизнь :: Проект
жизнь = Проект "Жизнь" [
    Действие Родиться (Возраст 0) Сделано,
    Проект "Образование" [
        Действие (Окончить Школу) (Возраст 16) Сделано,
        Действие (Окончить Университет) (Возраст 20) Сделано
        ],
    Проект "Семья" [
        Действие (Жениться Неизвестно) КогдаНибудь Делается,
        Действие (Родить Сына) КогдаНибудь НеСделано,
        Действие (Родить Дочь) КогдаНибудь НеСделано,
        Действие (Родить (Детей 1)) КогдаНибудь НеСделано
        ],
    Проект "Работа" [
        Действие (Подписать Контракт) КогдаНибудь НеСделано,
        Действие (Заработать $ foldr (*) 1 [1..20]) КогдаНибудь Делается
    ],
    Проект "Отдых" [
        Действие (Праздновать НовыйГод) (Между (Дата 31 Декабря 2009) (Дата 4 Января 2010)) Делается
    ],
    Действие Умереть КогдаНибудь НеСделано
    ]

вселенная :: Проект
вселенная = Проект "Все остальное" (repeat вселенная)

-- проект завершен, когда завершены все его действия
завершен :: Проект -> Bool
завершен (Действие _ _ Сделано) = True
завершен (Проект _ список) = all завершен список
завершен _ = False

-- nbgf ghbrjk
ответ :: Проект -> Integer
ответ _ = 42


Загрузка файла в интерпретаторе ghci

GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> :l now/gtd/gtd.hs
[1 of 1] Compiling Main             ( now/gtd/gtd.hs, interpreted )
Ok, modules loaded: Main.
*Main> ответ жизнь
42
*Main> ответ вселенная
42
*Main> завершен жизнь
False
*Main> завершен вселенная
*** Exception: stack overflow
*Main> 


показывает, что Вселенная больше стека :)

Хотелось бы узнать какие запросы или отчеты к GTD инструменту были бы Вам полезны?
Tags:
Hubs:
+7
Comments 2
Comments Comments 2

Articles