我记得 monad
是一个 monoid
。也就是说,存在一个关联二元运算 *
因此如果 ma
和 mb
是 monadic 值 那么 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
的追加或 Option
的 orElse
.
关于scala - Scala 中 Option 的关联二进制操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21826735/