Ru/Monad: Difference between revisions
(добавлены ссылки) |
mNo edit summary |
||
Line 96: | Line 96: | ||
** [http://rsdn.ru/article/haskell/haskell_part2.xml#E1JAC Мягкое введение в Haskell. Часть 9: О Монадах] | ** [http://rsdn.ru/article/haskell/haskell_part2.xml#E1JAC Мягкое введение в Haskell. Часть 9: О Монадах] | ||
** [http://ru.wikibooks.org/wiki/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D0%B8_%D0%BC%D0%BE%D0%BD%D0%B0%D0%B4%D1%8B_%D0%B2_Haskell%27%D0%B5#.D0.9C.D0.BE.D0.BD.D0.B0.D0.B4.D1.8B Основы функционального программирования/Монады в Haskell'е] | ** [http://ru.wikibooks.org/wiki/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B3%D0%BE_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F/%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D0%B8_%D0%B8_%D0%BC%D0%BE%D0%BD%D0%B0%D0%B4%D1%8B_%D0%B2_Haskell%27%D0%B5#.D0.9C.D0.BE.D0.BD.D0.B0.D0.B4.D1.8B Основы функционального программирования/Монады в Haskell'е] | ||
[[Category:Ru]] |
Latest revision as of 14:24, 4 April 2012
(перенесено из статьи введение в Haskell IO)
Немного глубже в do
Поначалу кажется, что do - какая-то чёрная магия, или встроенный синтаксис для грязных процедур. На самом деле всё это просто cинтаксический сахар, без которого можно обойтись, но который позволяет склеивать процедуры и делает их написание проще.
Для одного выражения do излишне:
main = do putStr "Привет!"
без do можно записать как:
main = putStr "Привет!"
Как же обойтись без do для нескольких действий?
main = do putStr "Как Вас зовут?"
putStr "Сколько Вам лет?"
putStr "Неплохой денёк сегодня!"
Тут do говорит, что действия идут одно за другим. Это переводится в оператор последовательности (>>):
main = (putStr "Как Вас зовут?") >> (putStr "Сколько Вам лет?") >> (putStr "Неплохой денёк сегодня!")
Более сложными являются примеры с (<-):
main = do a <- readLn
print a
Такой код переводится в:
main = readLn >>= (\a -> print a)
Выражения типа (x >>= (\y -> z)) означает "сделать x, взять его результат, подставить его в лямбду вместо y, вычислить z, и сделать z".
С этим оператором можно писать, к примеру, и так:
main = readLn >>= print
Чтобы закрепить принцип избавления от do, рассмотрим внимательно пример программы в трёх вариантах. Сначала идёт do, потом его перевод со скобками, и под конец - без них, что дозволительно благодаря приоритетам операторов:
main = main3
main1 = do putStr "Как Вас зовут? "
i <- readLn
putStr "Сколько Вам лет? "
v <- readLn
putStr "Привет, "
putStr i
putStr "! Неплохой денёк сегодня!"
main2 = (putStr "Как Вас зовут? ") >>
readLn >>= (
\i -> (
(putStr "Сколько Вам лет? ") >>
readLn >>= (
\v -> (
(putStr "Привет, ") >>
(putStr i) >>
(putStr "! Неплохой денёк сегодня!")
)
)
)
)
main3 = putStr "Как Вас зовут? " >>
readLn >>= \i ->
putStr "Сколько Вам лет? " >>
readLn >>= \v ->
putStr "Привет, " >>
putStr i >>
putStr "! Неплохой денёк сегодня!"
Зачем это всё знать? А все дело в том, что все эти операторы (и do) используются не только в процедурах, а и, к примеру, в списках. Их смысл можно даже переопределять!
Подробнее о списках:
a1 = do x <- [10,100,1000] -- перебрать все эти числа как x
y <- [1,2,3] -- перебрать 1..3 как y
return (x*y) -- слить (x*y) в список-результат
-- Результат: [10,20,30,100,200,300,1000,2000,3000]