Митап Haskell-программистов в «Лаборатории Касперского» (в смысле — ждем)

Чистый функциональный язык программирования
ICFP Programming Contest — международное соревнование по программированию, проводимое ежегодно летом с 1998 года. Результаты соревнования объявляются на Международной конференции по функциональному программированию. (с) Wikipedia
Это седьмая статья из цикла «Теория категорий для программистов». Предыдущие статьи уже публиковались на Хабре:
За понятием функтора стоит очень простая, но мощная идея (как бы заезжено это ни прозвучало). Просто теория категорий полна простых и мощных идей. Функтор есть отображение между категориями. Пусть даны две категории C и D, а функтор F отображает объекты из C в объекты из D — это функция над объектами. Если a — это объект из C, то будем обозначать его образ из D как F a (без скобок). Но ведь категория — это не только объекты, но еще и соединяющие их морфизмы. Функтор также отображает и морфизмы — это функция над морфизмами. Но морфизмы отображаются не как попало, а так, чтобы сохранять связи. А именно, если морфизм f из C связывает объект a с объектом b,
f :: a -> b
то образ f в D, F f, связывает образ a с образом b:
F f :: F a -> F b
(Надеемся, что такая смесь математических обозначений и синтаксиса Haskell понятна читателю. Мы не будем писать скобки, применяя функторы к объектам или морфизмам.)
Я подразумеваю, что читатель знает Haskell, по крайней мере, до монад.
Monad – это класс типов, позволяющий (неформально говоря) из функций, которые возвращают что то вроде MyMonad КакойтоТип выполнять некие функции, взаимодействующие с монадой. Функции, использующие монады, нужно связывать между собой специальными функциями (>>),(>>=),(=<<).
Так вот, Comonad – это тоже класс типов, который позволяет функциям взаимодействовать с эффектами комонады, только у этих функций комонада указывается не в возвращаемом типе, а в аргументе.
(Int, Bool)
вместо (Bool, Int)
, хотя они и содержат одни и те же данные. Однако произведение коммутативно с точностью до изоморфизма, задаваемого функцией swap
, которая обратна самой себе:swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)
— Для чего нужны монады?
— Для того, чтобы отделить чистые вычисления от побочных эффектов.
(из сетевых дискуссий о языке Haskell)
Шерлок Холмс и доктор Ватсон летят на воздушном шаре. Попадают в густой туман и теряют ориентацию. Тут небольшой просвет — и они видят на земле человека.
— Уважаемый, не подскажете ли, где мы находимся?
— В корзине воздушного шара, сэр.
Тут их относит дальше и они опять ничего не видят.
— Это был математик, – говорит Холмс.
— Но почему?
— Его ответ совершенно точен, но при этом абсолютно бесполезен.
(анекдот)
echo
:import System.Exit
main = do x <- getLine
putStrLn x
exitSuccess
putStrLn "Finished"
(1+) `fmap` (2, 3)
. А после этого проверьте полученный результат, например, в ghci
. У многих ли результат ручного вычисления совпал с тем, который выдала система? И если у вас результаты все же совпали, мне очень хотелось бы услышать хорошее объяснение того, как именно вам это удалось.