scala - 到底是什么让 Option 成为 Scala 中的 monad?

标签 scala haskell functional-programming monads option-type

我知道 monad 是什么以及如何使用它们。我不明白的是什么使得Option成为一个monad?

在 Haskell 中,monad Maybe 是一个 monad,因为它是从 Monad 类实例化的(该类至少有 2 个必要的函数 returnbind 使类 Monad 实际上成为一个 monad)。

但是在 Scala 中我们有这个:

sealed abstract class Option[+A] extends Product with Serializable { ... }
trait Product extends Any with Equals { ... }

与单子(monad)无关。

如果我在 Scala 中创建自己的类,默认情况下它会是一个 monad 吗?为什么不呢?

最佳答案

Monad 是一个概念,如果你愿意的话,它是一个抽象接口(interface),它简单地定义了一种组合数据的方式。

Option 支持通过 flatMap 进行组合,这几乎是佩戴“monad 徽章”所需的一切。

从理论角度来看,它还应该:

  • 支持 unit 操作(return,用 Haskell 术语来说)以从裸值创建 monad,在 Option 的情况下是 Some 构造函数
  • 尊重monadic laws

但这并没有被 Scala 严格执行。

scala 中的 Monad 是一个比 Haskell 中宽松得多的概念,并且方法更实用。 从语言的角度来看,单子(monad)唯一相关的是在 for 理解中使用的能力。

flatMap 是基本要求,您可以可选提供 mapwithFilterforeach .

但是,不存在像 Haskell 那样严格遵守 Monad 类型类的情况。

这是一个示例:让我们定义自己的 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
}

如您所见,我们仅实现了 mapflatMap(以及 toString 作为商品)。 恭喜,我们有了一个 monad!让我们尝试一下:

scala> for {
  a <- new MyMonad(2)
  b <- new MyMonad(3)
} yield a + b
// res1: MyMonad[Int] = 5

不错!我们没有进行任何过滤,因此不需要实现withFilter。另外,由于我们正在生成一个值,因此我们也不需要 foreach 。基本上你可以实现任何你想支持的东西,没有严格的要求。如果您尝试在 for 理解式中进行过滤,但尚未实现 withFilter,您只会收到编译时错误。

关于scala - 到底是什么让 Option 成为 Scala 中的 monad?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25361203/

相关文章:

scala - Scala 中具有依赖类型的参数的模式匹配的类型安全性

multithreading - 并发程序效率和CPU线程数

scala - 定义自引用 Scala 类(递归类)

haskell - 在多参数函数上使用美元符号

haskell - 我修改后的 zip 版本有什么问题?

java - 在 Java 8 列表上过滤

functional-programming - 函数式语言中的 'Pattern Matching' 是什么?

scala - 有没有办法使用scala过滤 Spark 数据框中不包含某些内容的字段?

scala - Akka:管道自己和 parent

haskell - mkWeak 的值参数严格吗?