最近简要介绍了Haskell,对于monad本质上是什么,简单,简洁,实用的解释是什么?
我发现我遇到的大多数解释都是相当难以接近的,缺乏实际细节.
谁首先说了以下几点?
monad只是endofunctors类别中的幺半群,问题是什么?
在一个不太重要的注意事项上,这是真的,如果是这样,你能给出一个解释(希望有一个可以被没有Haskell经验的人理解的那个)吗?
就OOP程序员所理解的而言(没有任何函数编程背景),monad是什么?
它解决了什么问题,它使用的最常见的地方是什么?
编辑:
为了澄清我一直在寻找的理解,让我们假设您正在将具有monad的FP应用程序转换为OOP应用程序.你会怎么做把monad的职责移植到OOP应用程序?
设计/构建大型功能程序的好方法是什么,特别是在Haskell中?
我已经阅读了很多教程(自己写一个方案是我最喜欢的,真实世界Haskell紧随其后) - 但大多数程序都相对较小,而且是单一目的.另外,我不认为它们中的一些特别优雅(例如,WYAS中的大量查找表).
我现在想要编写更大的程序,包含更多移动部件 - 从各种不同来源获取数据,清理数据,以各种方式处理数据,在用户界面中显示,持久化,通过网络进行通信等.一个最好的结构,这样的代码是易读,可维护,适应不断变化的要求?
有大量文献针对大型面向对象的命令式程序解决这些问题.像MVC,设计模式等的想法是实现广泛目标的理想规定,例如在OO风格中分离关注点和可重用性.此外,较新的命令式语言适合于"随着您的成长而设计"的重构风格,在我的新手看来,Haskell似乎不太适合.
Haskell有相同的文献吗?如何在功能性编程(单子,箭头,应用等)中使用异域控制结构的动物园最好地用于此目的?你能推荐什么最佳实践?
谢谢!
编辑(这是Don Stewart回答的后续行动):
@dons提到:"Monads在类型中捕获关键的建筑设计."
我想我的问题是:如何在纯函数式语言中考虑关键的架构设计?
考虑几个数据流的示例和几个处理步骤.我可以将数据流的模块化解析器编写为一组数据结构,我可以将每个处理步骤实现为纯函数.一个数据所需的处理步骤将取决于其值和其他数据.一些步骤之后应该是GUI更新或数据库查询等副作用.
什么是以正确方式绑定数据和解析步骤的"正确"方法?人们可以编写一个大功能,为各种数据类型做正确的事情.或者可以使用monad来跟踪到目前为止已处理的内容,并让每个处理步骤从monad状态获得接下来需要的任何内容.或者可以写很多单独的程序并发送消息(我不太喜欢这个选项).
他链接的幻灯片有一个我们需要的东西子弹:"将设计映射到类型/函数/类/ monad上的成语".什么是成语?:)
如果我有一个EnumeratorT
和一个相应的IterateeT
我可以一起运行它们:
val en: EnumeratorT[String, Task] = EnumeratorT.enumList(List("a", "b", "c"))
val it: IterateeT[String, Task, Int] = IterateeT.length
(it &= en).run : Task[Int]
Run Code Online (Sandbox Code Playgroud)
如果枚举器monad比iteratee monad"更大",我可以使用up
或者更一般Hoist
地"提升"iteratee以匹配:
val en: EnumeratorT[String, Task] = ...
val it: IterateeT[String, Id, Int] = ...
val liftedIt = IterateeT.IterateeTMonadTrans[String].hoist(
implicitly[Task |>=| Id]).apply(it)
(liftedIt &= en).run: Task[Int]
Run Code Online (Sandbox Code Playgroud)
但是,当iteratee monad比枚举器monad"更大"时,我该怎么办?
val en: EnumeratorT[String, Id] = ...
val it: IterateeT[String, Task, Int] = ...
it &= ???
Run Code Online (Sandbox Code Playgroud)
似乎没有任何Hoist
实例EnumeratorT
,也没有任何明显的"提升"方法.
在向某人解释什么是类型类X时,我很难找到正好是X的数据结构的好例子.
所以,我请求示例:
我认为Monad到处都有很多例子,但Monad的一个很好的例子与之前的例子有一些关系可以完成图片.
我寻找彼此相似的示例,区别仅在于属于特定类型类的重要方面.
如果有人能够设法在这个层次结构的某个地方隐藏一个Arrow的例子(它是在Applicative和Monad之间吗?),那也会很棒!
这些天有很多关于单子的讨论.我已经阅读了一些文章/博客文章,但我不能用他们的例子来完全掌握这个概念.原因是monad是一个函数式语言概念,因此这些例子都是我没有使用过的语言(因为我没有深入使用过函数式语言).我无法深入掌握语法以完全遵循这些文章......但我可以告诉它有一些值得理解的东西.
但是,我非常了解C#,包括lambda表达式和其他功能特性.我知道C#只有一部分功能特性,所以monad不能用C#表示.
但是,肯定有可能传达这个概念吗?至少我希望如此.也许您可以将C#示例作为基础,然后描述C#开发人员希望他可以从那里做什么,但不能,因为该语言缺乏函数式编程功能.这太棒了,因为它会传达monad的意图和好处.所以这就是我的问题:你可以给一个C#3开发人员提供monad的最佳解释是什么?
谢谢!
(编辑:顺便说一下,我知道SO上至少有3个"什么是monad"问题.然而,我遇到了同样的问题......所以这个问题需要imo,因为C#-developer焦点.谢谢.)
任何人都可以给出一些指针,说明为什么Haskell中的不纯计算被建模为monad?
我的意思是monad只是一个有4个操作的界面,那么建模副作用的原因是什么呢?
monads ×10
haskell ×7
applicative ×1
c# ×1
c#-3.0 ×1
enumerator ×1
free-monad ×1
functor ×1
iterate ×1
lambda ×1
large-scale ×1
monoids ×1
oop ×1
scala ×1
scalaz ×1
terminology ×1