scala - Scala 中 Option 的关联二进制操作

标签 scala functional-programming monads monoids

我记得 monad 是一个 monoid。也就是说,存在一个关联二元运算 * 因此如果 mambmonadic 值 那么 ma * mb 也是一个 monadic 值。

如果以上是正确的,那么 Scala 中 Option 的二进制操作是什么?例如,Some(1) * Some(2) 中的 * 可以是什么?

最佳答案

(这个答案从 https://stackoverflow.com/a/3870310/200266 中窃取了它的定义,只是试图给出一个粗略的解释。我对范畴论的了解相当基础。)

在一般情况下,只有当您考虑仿函数(例如 T => Option[T])而不是值(例如 Some(3)None)时,说 monad 也是幺半群才有效。

作为一个关于值的幺半群的例子,让我们看一下 List[T] .

我们有一个二元运算• : S × S -> S:

def append[T](list1: List[T], list2: List[T]): List[T] = list1 append list2

和空列表 Nil显然是身份元素。没有 append但是,每个 monad 中都有方法,因此上述内容不能推广到所有 monad。让我们稍微改变一下二元运算的定义。

现在,在上述情况下,× 可以看作是返回输入值的元组:

List[T] × List[T] => (List[T], List[T])

还有我们的append函数接收此元组作为其输入。

但是,我们可以将元组操作×更改为,现在表示仿函数组合。

(K => List[K]) ∘ (K => List[K]) => (K => List[List[K]])

因此,我们正在寻找满足 μ : T ∘ T -> T 或更具体的函数

(K => List[List[K]]) => (K => List[K])

该操作在 Scala 中称为 flatten (Haskell 中的 join)。 monoid 的身份元素是 monad 构造函数,它在 Scala 中没有通用名称(在 Haskell 中为 return),但它存在于每个 monad 中。例如。 x => List(x) .

总结一下,考虑到这个问题和这个问题中的其他答案,monad 如何成为幺半群存在三种可能性:

A) 在仿函数组合下,每个单子(monad)也是上述意义上的幺半群。

B) 每个单子(monad) M[T]如果对于 T: ~+~ 也有一个幺半群(通过一些二元运算 for {x <- ma; y <- mb} yield x ~+~ y),则有一个幺半群

C) 一些 monads 可能有一个或多个不同于 B 中的特定幺半群。例如 List的追加或 OptionorElse .

关于scala - Scala 中 Option 的关联二进制操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21826735/

相关文章:

json - 在模式 rdd 中分解 json 数组

collections - 在 Java 中将枚举转换为映射

functional-programming - Blackheath 的 "Functional reactive programming"书,2.6.3 部分澄清

functional-programming - 对于任何使用函数式编程的项目?

haskell - 单子(monad)变压器的解剖

haskell - Haskell中的*>和>>有什么区别?

scala - 函数在 Spark 中返回一个空列表

scala - Scala中的A#B是什么意思

scala - 将 S3(法兰克福)与 Spark 结合使用

haskell - 如何让它变得更好? "Maybe Bool"看起来不太好