Monoids
当您意识到您可以站在巨人的肩膀上并利用常见的抽象和为使用它们而构建的库时,您可能会发现生活变得更加轻松。为此,这个问题基本上是关于处理
幺半群(有关此问题的更多信息,请参见下面的相关问题),并且有问题的库称为scalaz。
使用 scalaz FP,这只是:
def add(a: Option[Int], b: Option[Int]) = ~(a |+| b)
更重要的是,这适用于任何幺半群 M:
def add[M: Monoid](a: Option[M], b: Option[M]) = ~(a |+| b)
更有用的是,它适用于放置在Foldable
容器内的任意数量的它们:
def add[M: Monoid, F: Foldable](as: F[Option[M]]) = ~as.asMA.sum
请注意,除了显而易见的Int
,之外String
,一些相当有用的幺半群Boolean
是:
Map[A, B: Monoid]
A => (B: Monoid)
Option[A: Monoid]
事实上,提取自己的方法几乎不值得费心:
scala> some(some(some(1))) #:: some(some(some(2))) #:: Stream.empty
res0: scala.collection.immutable.Stream[Option[Option[Option[Int]]]] = Stream(Some(Some(Some(1))), ?)
scala> ~res0.asMA.sum
res1: Option[Option[Int]] = Some(Some(3))
一些相关问题
问:什么是幺半群?
幺半群是M
存在关联二元运算(M, M) => M
和I
在此运算下的恒等式的类型,因此mplus(m, I) == m == mplus(I, m)
对于所有m
类型M
问:什么是|+|
?
这只是mplus
二进制操作的 scalaz 简写(或 ASCII 疯狂,ymmv)
问:什么是~
?
它是一个一元运算符,意思是“或身份”,由 scalaz 库改造(使用 scala 的隐式转换)到Option[M]
ifM
是一个幺半群。显然,非空选项返回其内容;一个空选项被幺半群的身份替换。
问:什么是asMA.sum
?
AFoldable
基本上是一种可以折叠的数据结构(foldLeft
例如 )。回想一下,它foldLeft
需要一个种子值和一个操作来组成连续的计算。在对幺半群求和的情况下,种子值是恒等式I
,运算是mplus
。asMA.sum
因此,您可以调用Foldable[M : Monoid]
. asMA
由于名称与标准库的sum
方法冲突,您可能需要使用。
一些参考资料