アレッ*_*ックス 36 monads haskell functional-programming scala maybe
我知道monad是什么以及如何使用它们.我不明白的是,是什么让Option一个单子?
在Haskell中,monad Maybe是一个monad,因为它是从Monad类中实例化的(它具有至少2个必要的函数return,bind并且实现了类Monad,实际上是monad).
但是在Scala我们有这个:
sealed abstract class Option[+A] extends Product with Serializable { ... }
trait Product extends Any with Equals { ... }
Run Code Online (Sandbox Code Playgroud)
没有任何与monad相关的东西.
如果我在Scala中创建自己的类,默认情况下它是monad吗?为什么不?
Gab*_*lla 56
Monad 是一个概念,如果你愿意,它是一个抽象的接口,它只是定义了一种组合数据的方式.
Option支持组合通过flatMap,这几乎是穿"monad徽章"所需的一切.
从理论的角度来看,它还应该:
unit操作(return在Haskell术语中)从一个裸值创建一个monad,如果Option是Some构造函数但这并不是Scala严格执行的.
scala中的Monads是一个更宽松的概念,在Haskell中,这种方法更实用.从语言的角度来看,monad唯一与之相关的是用于理解的能力.
flatMap是一个基本要求,您可以选择提供map,withFilter和foreach.
但是,对于Monad类型类没有严格的一致性,就像Haskell一样.
这是一个例子:让我们定义我们自己的monad.
class MyMonad[A](value: A) {
def map[B](f: A => B) = new MyMonad(f(value))
def flatMap[B](f: A => MyMonad[B]) = f(value)
override def toString = value.toString
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我们只是实施map和flatMap(以及toString作为商品).恭喜,我们有一个monad!我们来试试吧:
scala> for {
a <- new MyMonad(2)
b <- new MyMonad(3)
} yield a + b
// res1: MyMonad[Int] = 5
Run Code Online (Sandbox Code Playgroud)
太好了!我们没有进行任何过滤,因此我们不需要实现withFilter.此外,由于我们正在产生价值,我们也不需要foreach.基本上你实现了你想要支持的任何东西,没有严格的要求.如果您尝试过滤for-comprehension并且尚未实现withFilter,则只会出现编译时错误.
Ion*_*tan 13
任何(部分)实现的东西,通过鸭子打字,FilterMonadic特征被认为是Scala中的monad.这与在Haskell中表示monad或Monad在scalaz中表示类型类的方式不同.但是,为了使forScala 中的理解语法糖受益,对象必须暴露FilterMonadic特征中定义的一些方法.
此外,在Scala中,Haskell return函数的等价物是yield用于从for理解中生成值的关键字.desugaring yield是map对"monad"方法的调用.
我所说的方式是,monads作为一种设计模式与一流的抽象之间正在出现区别.Haskell以Monad类型类的形式具有后者.但是如果你的类型具有(或可以实现)monadic操作并遵守法律,那么这也是一个monad.
现在,您可以在Java 8的库中看到monads作为设计模式.Java 8中的Optional和Stream类型带有一个of与Haskell对应的静态方法return和一个flatMap方法.但是没有Monad类型.
介于两者之间你也有"鸭式"的方法,正如IonuţG.Stan的回答所说的那样.C#也有这个 - LINQ语法不依赖于特定类型,而是可以与任何实现某些方法的类一起使用.