在实践中使用monad,monoids,functor和箭头

时间:2011-11-28 11:41:10

标签: haskell monads arrows functor monoids

我最近遇到了关于函数式编程不同方面的有用资源的post,例如monad和monoids等。

但问题是 - 普通程序员可以用这些概念做些什么。我经常对这些问题进行“学术”研究。但是,我从未在实践中(在实际项目中)遇到任何人使用它们。

所以问题是 - 在Haskell中是否有任何广泛使用的开源项目真正利用这些东西,这些项目在“生产”软件中证明了这一概念的实际必要性,而不是在“学术”中软件写的“只是为了好玩”。制作这样的清单会很酷:

  • Monads - 在A和B等项目中使用,因为否则这样的代码看起来会复杂得多。
  • 幺半群也一样。
  • 仿函数相同。
  • 箭头也一样。

3 个答案:

答案 0 :(得分:9)

其中许多概念在Haskell代码中是如此隐含,因此更容易列出不使用它们的示例(假设您可以找到一个)。每个Haskell程序都使用monad,至少对IO来说。

所有这些都被广泛使用,因为它们是代码中经常出现的抽象。考虑仿函数:对容器进行映射是一个相当普遍的需求,因此为任何类似容器的数据结构提供单一接口是有意义的,这正是Functor提供的。碰巧甚至“容器”的概念比仿函数抽象更具体,但希望这证明了这一点。

Monads:XMonad窗口管理器是一个广泛使用的程序,它广泛使用monad变换器和zipper structureSTM是一个为新monad提供有用属性的库。

Monoids:Sequence包中的containers结构为implemented with monoids。此外,monoids被广泛用于模型集,列表和类似,因为两个monoid操作提供了一个空列表和连接(或一个空集和联合)。

Arrows:YampaHXT(Haskell XML Toolbox)立即浮现在脑海中。

Functors随处可见。 monadic代码有很多<$> s是很常见的,这意味着Functor实例正在使用中。 Most Haskell parsers大量使用仿函数。

答案 1 :(得分:6)

我正在为现实世界的应用程序高效地使用箭头和单子(以及编码器)。我的功能反应式编程(FRP)库Netwire结合了您提到的所有四个概念以及更多,而FRP本身也是一种设计模式,您通常可以从学者那里了解到这一点。这些是使用的概念:

  • 箭头和箭头变换器:Netwire提供Wire类型,这是一个箭头变换器。
  • Monads和monad变换器:Wire通常转换为由Kleisli箭头包裹的一堆monad变换器。
  • 电线抑制(如异常或未发生事件)使用幺半群。

第3版即将发布(我希望今天发布),它还会将(非关联)类型系列带入游戏中。

答案 2 :(得分:6)

除了John L'之外,Ertes的回答也很棒。我只是想添加一些关于仿函数和幺半群的东西:我相信大部分Haskell术语虽然精确,但对于新的Haskell程序员来说可能有些偏见。我总是告诉新人,monoids可以被认为是“appendables”,而functor可以被认为是“mappables”。显然,这种简化会有一些损失,但它有助于克服语言的最初词汇障碍。 monoid接口(类型类)具有“append”和“identity”函数,而functor只指定了map函数。长期追加和映射的概念之间存在一些滑点(例如求和是一种附加),但基本思想仍然存在。

作为附加和映射的简单接口,monoids和functors很快就会发现它们有很多用途:只要你的数据结构需要支持附加或映射,你就有时间使你的数据strcuture成为monoid或者仿函数可以简化过程。

希望这很有帮助。

接下来,这里列出了您要问的库。

Functors:查看像attparsec这样的解析库。 http://hackage.haskell.org/package/attoparsec-0.10.0.2 Functors允许您轻松编写解析器,以便您可以编写易于编写,易于阅读的解析器,甚至可以编写复杂的数据。将attoparsec解析器与可比较的正则表达式进行对比!

Monoid:查看任何数组,向量库(http://hackage.haskell.org/packages/archive/vector/0.9/doc/html/Data-Vector.html)以查看Monoid用于实现monoids的可附加性的用法。此外,这是一篇很好的文章,可以让幺半群为你工作http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html

Monads:查看Data.Binary - 一个简单而基本的Haskell库 - 用于Monads的完美用例。 http://hackage.haskell.org/packages/archive/binary/0.4.1/doc/html/Data-Binary.html通过使用monad,您可以编写复杂的指令系列,以几乎必须的方式解析二进制文件。