【问题标题】:Using monads, monoids, functors and arrows in practice在实践中使用单子、幺半群、函子和箭头
【发布时间】:2011-11-28 11:41:09
【问题描述】:

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

但问题是 - 普通程序员可以从这些概念中获得什么用处。我经常遇到关于这些问题的“学术”研究。但是,我从未在实践中(在实际项目中)遇到过使用它们的人。

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

  • Monads - 用于 A 和 B 等项目,否则这样的代码看起来会复杂得多。
  • 幺半群也是如此。
  • 函子也是如此。
  • 箭头也是如此。

【问题讨论】:

  • 也许你会对Typeclassopedia 感兴趣。
  • 谢谢,一个有趣的资源,我去研究一下
  • 我并不是要听起来像精英主义者,但如果你真的自己学习了这些概念,你就会发现它们的实用性无处不在。任何执行 IO 的重要应用程序肯定会充分利用 IO 的 Monad 和 Functor 实例。
  • 是的,这是真的,但这是我迄今为止看到的唯一应用程序,这就是导致问题的原因。我才刚刚开始使用这些概念,所以我想知道它们的实用性

标签: haskell monads arrows functor monoids


【解决方案1】:

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

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

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

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

箭头:YampaHXT(Haskell XML 工具箱)立即浮现在脑海。

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

【讨论】:

    【解决方案2】:

    我在现实世界的应用程序中高效地使用箭头和单子(因此也包括函子)。我的函数响应式编程(FRP)库Netwire结合了你提到的所有四个概念以及更多,FRP 本身也是一种设计模式,你通常从学术界知道。这些是使用的概念:

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

    第 3 版即将发布(我希望是今天),它还将把(非关联的)类型家族带入游戏中。

    【讨论】:

      【解决方案3】:

      Ertes 的回答和 John L 的回答都很棒。我只是想补充一些关于函子和幺半群的东西:我相信 Haskell 的大部分术语,虽然在其精确度上是好的,但对于新的 Haskell 程序员来说可能有点反感。我总是告诉新手,幺半群可以被认为是“可附加的”,而函子可以被认为是“可映射的”。显然,这种简化有一些损失,但它有助于克服语言最初的词汇障碍。 monoid 接口(typeclass)具有“append”和“identity”函数,而 functor 只指定了一个 map 函数。附加和映射的长期思想之间存在一些偏差(例如求和是一种附加),但基本思想是成立的。

      作为附加和映射的简单接口,monoids 和 functors 很快就会显示出自己有很多用途:任何时候你的数据结构需要支持附加或映射,你就有时间让你的数据结构成为 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 用于实现 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 通过使用 monads,您可以编写一系列复杂的指令来以几乎命令式的方式解析二进制文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-05
        • 2014-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        相关资源
        最近更新 更多