Я читаю "Learn You a Haskell", и я уже рассмотрел приложение, и теперь я на моноидах. У меня нет проблем с пониманием обоих, хотя я нашел применение полезным на практике, а моноид - не совсем так. Поэтому я думаю, что я ничего не понимаю о Haskell.
Во-первых, говоря о Applicative
, он создает нечто вроде единообразного синтаксиса для выполнения различных действий над "контейнерами". Таким образом, мы можем использовать обычные функции для выполнения действий над Maybe
, списками, IO
(должны ли я сказать монады? Я еще не знаю монад), функции:
λ> :m + Control.Applicative
λ> (+) <$> (Just 10) <*> (Just 13)
Just 23
λ> (+) <$> [1..5] <*> [1..5]
[2,3,4,5,6,3,4,5,6,7,4,5,6,7,8,5,6,7,8,9,6,7,8,9,10]
λ> (++) <$> getLine <*> getLine
one line
and another one
"one line and another one"
λ> (+) <$> (* 7) <*> (+ 7) $ 10
87
Таким образом, аппликация является абстракцией. Я думаю, что мы можем жить без него, но это помогает четко выражать некоторые идеи и прекрасно.
Теперь взглянем на Monoid
. Это также абстракция и довольно простая. Но это помогает нам? Для каждого примера из книги кажется очевидным, что есть более четкий способ сделать что-то:
λ> :m + Data.Monoid
λ> mempty :: [a]
[]
λ> [1..3] `mappend` [4..6]
[1,2,3,4,5,6]
λ> [1..3] ++ [4..6]
[1,2,3,4,5,6]
λ> mconcat [[1,2],[3,6],[9]]
[1,2,3,6,9]
λ> concat [[1,2],[3,6],[9]]
[1,2,3,6,9]
λ> getProduct $ Product 3 `mappend` Product 9
27
λ> 3 * 9
27
λ> getProduct $ Product 3 `mappend` Product 4 `mappend` Product 2
24
λ> product [3,4,2]
24
λ> getSum . mconcat . map Sum $ [1,2,3]
6
λ> sum [1..3]
6
λ> getAny . mconcat . map Any $ [False, False, False, True]
True
λ> or [False, False, False, True]
True
λ> getAll . mconcat . map All $ [True, True, True]
True
λ> and [True, True, True]
True
Итак, мы заметили некоторые шаблоны и создали новый класс типа... Хорошо, мне нравится математика. Но с практической точки зрения, что точка Monoid
? Как это помогает нам лучше выражать идеи?