简体   繁体   English

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

[英]Application of understanding monad in real world

I'm studying functional programming in Scala and I learnt term monad. 我正在Scala学习函数式编程,并且学习了术语monad。 In short monad is: 简而言之,monad是:

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

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

I know monad is just a concept based on above 2 rules. 我知道monad只是基于上述2条规则的概念。 And we can meet many monads in real world such as List , Future .... 我们可以在现实世界中遇到许多单子,例如ListFuture ...。

The only one problem I don't know is: why should we know term "monad" as comparing to understanding List apis, Future apis or anything apis ... Is understanding monad help us write better code or can design better functional code structure. 我不知道的唯一一个问题是:与理解List api,Future api或任何api相比,为什么我们应该知道术语“ monad”?了解monad可以帮助我们编写更好的代码或可以设计更好的功能代码结构。

Thanks 谢谢

Because Monad already is a known term in category theory. 因为Monad已经是类别理论中的已知术语。 There are also 3 very important Monad laws, that a Monad has to adhere to. Monad还必须遵守3条非常重要的Monad法律。

In theory, we could call Monads whatever we'd like, ie "FlatMappable" or "Bindable", but the name "Monad" is already an established term in the functional programming community and is deeply linked to the Monad laws. 从理论上讲,我们可以将Monad命名为“ FlatMappable”或“ Bindable”,但“ Monad”这个名称已经在功能编程社区中确立了名称,并与Monad法律紧密联系。

As to why you should learn to appreciate Monads over learning each api individually, it's all about abstraction and reuse of knowledge. 至于为什么您应该学习欣赏Monad而不是单独学习每个api,这全都是关于知识的抽象和重用。 Oftentimes when we look at a new concept we compare them to concepts we already know. 通常,当我们查看一个新概念时,会将它们与我们已经知道的概念进行比较。

If you already understand the Future Monad, understanding the Task Monad will be much easier. 如果您已经了解了Future Monad,那么了解Task Monad将更加容易。

It's also good to mention, that for-comprehensions in Scala work exclusively on Monads. 值得一提的是,Scala中for-comprehensions仅适用于Monads。 In fact for-comprehensions are just syntactic sugar for flatMap and map (there's also filter , but that's not incredibly relevant to Monads). 实际上for-comprehensions只是flatMapmap语法糖(也有filter ,但这与Monads无关紧要)。 So recognizing if something is a Monad instance, enables you to utilize this extra piece of syntactic sugar. 因此,识别某物是否为Monad实例,可以使您利用这块额外的语法糖。

Also once you fully grasp the abstraction you can make use of concepts like Monad transformers, where the actual type of the Monad is less important. 同样,一旦您完全掌握了抽象,就可以使用Monad变压器之类的概念,其中Monad的实际类型不太重要。

Lastly, here are the Monad laws for completeness sake: 最后,出于完整性考虑,以下是Monad法律:

  • Left identity: M[F].pure(x).flatMap(f) == f(x) 左身份: M[F].pure(x).flatMap(f) == f(x)
  • Right identity: m.flatMap(pure(_)) == m 正确的身份: m.flatMap(pure(_)) == m
  • Associativity: m.flatMap(f).flatMap(g) == m.flatMap(x => f(x).flatMap(g)) 关联性: m.flatMap(f).flatMap(g) == m.flatMap(x => f(x).flatMap(g))

About Monad API vs concrete APIs: 关于Monad API与具体API:

An example could be Free Monad pattern. 一个示例可以是Free Monad模式。 It essentialy uses (at least) two monads: first one is wrapping your DSL's expressions, and the second one is effect monad, that is, modality that you interpret your expressions in (Option corresponds to something that could fail, Future also adds latency etc). 它必须使用(至少)两个monad:第一个是包装DSL的表达式,第二个是effect的monad,即解释表达式的方式(Option对应于可能失败的东西,Future还增加了延迟等)。 )。

To be more concrete: consider a task where you have some latency, and you decide to use Futures. 更具体地讲:考虑一个有一定延迟的任务,然后您决定使用期货。 How will you unit test that? 您将如何对它进行单元测试? Return some futures and then use Await? 返回一些期货,然后使用“等待”? Apart from adding unnecessary complexity, you can run into some problems with that. 除了增加不必要的复杂性之外,您还会遇到一些问题。 And you won't actually need to use Futures for some tests. 而且您实际上不需要使用Future进行某些测试。 The answer is to parametrize methods that are supposed to use Futures with Monad, so you can just use Identity monad, or Option, and just forget about aforementioned problem. 答案是对应该使用Futures与Monad进行参数化的方法,因此您可以只使用Identity monad或Option,而不必理会上述问题。

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

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