简体   繁体   English

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

[英]Using monads, monoids, functors and arrows in practice

I recently ran into this post about useful resources for different aspects of functional programming, such as monads and monoids, etc. 我最近在这篇文章中遇到了关于函数式编程不同方面的有用资源,比如monad和monoids等。

But the question is - what use can an average programmer make out of such concepts. 但问题是 - 普通程序员可以用这些概念做些什么。 I often run into "academic" researches about those issues. 我经常对这些问题进行“学术”研究。 However, I've never met in practice (in a real project) anyone using them. 但是,我从未在实践中(在实际项目中)遇到任何人使用它们。

So the question is - are there any widely-used open-source projects in Haskell that really make use of such things, such projects that demonstrate the actual necessity of this concepts in "production" software, not in the "academic" software written "just for fun". 所以问题是 - 在Haskell中是否有任何广泛使用的开源项目真正利用这些东西,这些项目在“生产”软件中证明了这一概念的实际必要性,而不是在“学术”软件中写的“纯娱乐”。 It would be cool to make a list like this: 制作这样的列表会很酷:

  • Monads - used in projects like A and B because otherwise such piece of code would look much more complicated. Monads - 在A和B等项目中使用,因为否则这样的代码看起来会复杂得多。
  • The same for monoids. 幺半群也一样。
  • The same for functors. 仿函数也一样。
  • The same for arrows. 箭头也一样。

Many of these concepts are so implicit in Haskell code it's easier to list examples that don't use them (assuming you can find one). 其中许多概念在Haskell代码中是如此隐含,因此更容易列出不使用它们的示例(假设您可以找到一个)。 Every Haskell program uses monads, at least for IO. 每个Haskell程序都使用monad,至少对于IO。

All of these are widely used because they're abstractions that appear very frequently in code. 所有这些都被广泛使用,因为它们是在代码中经常出现的抽象。 Consider functors: mapping over a containers is a fairly common need, so it makes sense to have a single interface for any container-like data structure, which is exactly what Functor provides. 考虑仿函数:对容器进行映射是一个相当普遍的需求,因此为任何类似容器的数据结构提供单一接口是有意义的,这正是Functor提供的。 It happens that even the concept of a "container" is more concrete than the functor abstraction, but hopefully this demonstrates the point. 碰巧甚至“容器”的概念比仿函数抽象更具体,但希望这证明了这一点。

Monads: The XMonad window manager is a widely-used program which makes extensive use of monad transformers and the zipper structure . Monads: XMonad窗口管理器是一个广泛使用的程序,它广泛使用monad变换器和拉链结构 STM is a library that provides a new monad with useful properties. STM是一个为新monad提供有用属性的库。

Monoids: the Sequence structure in the containers package is implemented with monoids . Monoids: containers包中的Sequence结构使用monoids实现 Also, monoids are widely used to model sets, lists, and similar because the two monoid operations provide an empty list and concatenation (or an empty set and union). 此外,monoids被广泛用于模型集,列表和类似,因为两个monoid操作提供空列表和连接(或空集和联合)。

Arrows: Yampa and HXT (Haskell XML Toolbox) immediately come to mind. 箭头: YampaHXT (Haskell XML Toolbox)立即浮现在脑海中。

Functors show up everywhere. Functors到处出现。 It's fairly common for monadic code to have a lot of <$> s, which means that the Functor instance is in use. monadic代码有很多<$> s是很常见的,这意味着Functor实例正在使用中。 Most Haskell parsers make heavy use of functors. 大多数 Haskell 解析器都大量使用仿函数。

I'm using arrows and monads (and thus also functors) productively for real world applications. 我正在为现实世界的应用程序高效地使用箭头和单子(以及编码器)。 My functional reactive programming (FRP) library Netwire combines all four concepts you mentioned and more, and FRP itself is also a design pattern, which you usually know from academics. 我的功能反应式编程(FRP)库Netwire结合了您提到的所有四个概念以及更多,而FRP本身也是一种设计模式,您通常从学术界知道。 These are the concepts used: 这些是使用的概念:

  • Arrows and arrow transformers: Netwire provides the Wire type, which is an arrow transformer. 箭头和箭头变换器:Netwire提供Wire类型,它是一个箭头变换器。
  • Monads and monad transformers: Wire usually transforms to a stack of monad transformers wrapped by a Kleisli arrow. Monads和monad变换器: Wire通常KleisliKleisli箭头包裹的monad变换器。
  • Wire inhibition (like exceptions or non-happened events) uses a monoid. 线路抑制(如异常或未发生事件)使用幺半群。

Version 3 is about to be released (I hope today), which will also bring (non-associated) type families into the game. 版本3即将发布(我希望今天),它还会将(非关联)类型系列带入游戏中。

Ertes answer as well as John L's are great. Ertes的答案以及John L's都很棒。 I just want to add something about functors and monoids: I believe that much of the Haskell terminology, while virtuous in its precision, can be a bit off-putting to new Haskell programmers. 我只是想添加一些关于仿函数和幺半群的东西:我相信大部分Haskell术语虽然精确,但对于新的Haskell程序员来说可能有些偏见。 I always tell newcomers that monoids can be thought of as "appendables" and functors as "mappables". 我总是告诉新人,monoids可以被认为是“appendables”,而functor可以被认为是“mappables”。 Obviously, there is some loss to this simiplification but it helps get over the initial lexical hurdles of the languages. 显然,这种简化会有一些损失,但它有助于克服语言的最初词汇障碍。 The monoid interface (typeclass) has the "append" and "identity" functions, whereas the functor just specifies a map function. monoid接口(类型类)具有“append”和“identity”函数,而functor只指定了map函数。 There is some slippage between the perennial idea of appending and mapping (for instance summation is a kind of appending) but the basic idea holds. 长期追加和映射的概念之间存在一些滑点(例如总和是一种附加),但基本思想仍然存在。

Taken as just simple interfaces for appending and mapping, monoids and functors quickly reveal themselves to have many uses: any time your data structure needs to support appending or mapping, you have a time wherein making your data strcuture an instance of monoid or functor could simplify the process. 作为附加和映射的简单接口,monoids和functors很快就会发现它们有很多用途:只要你的数据结构需要支持追加或映射,你就有时间使你的数据strcuture成为monoid或functor的实例可以简化这个过程。

Hope that was helpful. 希望这很有帮助。

As an afterward, here is a list of libraries you were asking about. 接下来,这是您要询问的库列表。

Functors: Look at a parsing library like attparsec. 函数:查看像attparsec这样的解析库。 http://hackage.haskell.org/package/attoparsec-0.10.0.2 Functors allow you to easily compose parsers so that you can write easy-to-compose, easy-to-read parsers for even complicated data. http://hackage.haskell.org/package/attoparsec-0.10.0.2 Functors允许您轻松编写解析器,以便您可以编写易于编写,易于阅读的解析器,甚至可以编写复杂的数据。 Contrast an attoparsec parser to a comparable regex! 将attoparsec解析器与可比较的正则表达式进行对比!

Monoid: Look at any array, vector library ( http://hackage.haskell.org/packages/archive/vector/0.9/doc/html/Data-Vector.html ) to see the uses of Monoid to implement the appendability of monoids. Monoid:查看任何数组,矢量库( http://hackage.haskell.org/packages/archive/vector/0.9/doc/html/Data-Vector.html ),看看Monoid用于实现monoids的可附加性。 Also, this is a great article for putting monoids to work for you http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html 此外,这是一篇很棒的文章,可以让monoids为你工作http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html

Monads: look at Data.Binary - a simple and fundamental Haskell library - for a perfect use case of Monads. Monads:查看Data.Binary - 一个简单而基本的Haskell库 - 用于Monads的完美用例。 http://hackage.haskell.org/packages/archive/binary/0.4.1/doc/html/Data-Binary.html By using monads, you can write complicated series of instructions for parsing binary files in an almost-imperative fashion. http://hackage.haskell.org/packages/archive/binary/0.4.1/doc/html/Data-Binary.html通过使用monad,您可以编写复杂的指令系列,以几乎必须的方式解析二进制文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM