【发布时间】:2014-12-01 13:21:51
【问题描述】:
我正在阅读 Learn You a Haskell 并且我已经介绍了应用程序,现在我正在学习幺半群。我对两者的理解都没有问题,尽管我发现 applicative 在实践中很有用,而 monoid 并非如此。所以我想我对 Haskell 有一些了解。
首先,说到Applicative,它创建了类似统一语法的东西来对“容器”执行各种操作。所以我们可以使用普通函数对Maybe、列表、IO(我应该说monads吗?我还不知道monads)执行操作,函数:
λ> :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
所以 applicative 是一种抽象。我认为我们可以没有它,但它有助于清楚地表达一些想法模式,这很好。
现在,让我们看看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 的意义何在?它如何帮助我们更好地表达想法?
【问题讨论】:
-
如果你想深入研究一些真正展示幺半群力量的高级材料,请查看finger trees(
Data.Sequence背后的引擎)。我敢肯定还有一些我现在想不出的更简单的例子。 -
我建议您阅读这篇出色的 Dan piponi's 文章。
-
另外我建议阅读Monoids and Finger Trees,它展示了我们如何使用相同的代码对树进行操作,并通过插入不同的幺半群来实现不同的数据结构。