理解monad在现实世界中的应用

时间:2017-03-14 10:57:27

标签: scala functional-programming monads

我正在学习Scala中的函数式编程,我学习了术语monad。简而言之,monad是:

trait M[A] {
  def flatMap[B](f: A => M[B]): M[B]
}

def unit[A](x: A): M[A]

我知道monad只是一个基于上述2条规则的概念。我们可以在现实世界中遇到许多monad,例如ListFuture ....

我不知道的唯一一个问题是:为什么我们应该将术语“monad”比作理解List apis,Future apis或者任何apis ... ...理解monad帮助我们编写更好的代码或者设计更好的功能代码结构。

由于

2 个答案:

答案 0 :(得分:7)

因为Monad已经是类别理论中的一个已知术语。还有3个非常重要的Monad法律,Monad必须坚持。

理论上,我们可以将Monads称为任何我们想要的,即“FlatMappable”或“Bindable”,但“Monad”这个名称已经是功能编程社区中的既定术语,并且与Monad法律密切相关。

至于为什么你应该学会欣赏Monads而不是单独学习每个api,这都是关于知识的抽象和重用。通常,当我们看一个新概念时,我们会将它们与我们已经知道的概念进行比较。

如果您已经了解未来Monad,那么理解Task Monad会更容易。

值得一提的是,Scala中的for-comprehensions专门用于Monads。事实上,for-comprehensions只是flatMapmap的语法糖(还有filter,但这与Monads并不相关)。因此,如果某些东西是Monad实例,则可以使用这一额外的句法糖。

一旦你完全掌握了抽象,你就可以利用像Monad变换器这样的概念,其中Monad的实际类型并不那么重要。

最后,为了完整起见,这是Monad法律:

  • 左侧身份:M[F].pure(x).flatMap(f) == f(x)
  • 正确的身份:m.flatMap(pure(_)) == m
  • 相关性:m.flatMap(f).flatMap(g) == m.flatMap(x => f(x).flatMap(g))

答案 1 :(得分:0)

关于Monad API与具体API:

一个例子可能是Free Monad模式。它主要使用(至少)两个monad:第一个是包装你的DSL表达式,第二个是效果monad,即你解释你的表达式的模态(Option对应于可能失败的东西,Future也增加了延迟等)。

更具体一点:考虑一个你有一些延迟的任务,你决定使用期货。你将如何进行单元测试呢?返回一些期货,然后使用Await?除了增加不必要的复杂性,你可能会遇到一些问题。而且你实际上不需要使用Futures进行一些测试。答案是参数化应该使用期货与Monad的方法,这样你就可以使用Identity monad或Option,而忘记上述问题。

相关问题