我尝试学习/理解一些scalaz。为此,我从示例开始:
List(3, 4, 5).asMA.foldMap(x => x)
=> 12 //(3+4+5)
def foldMap[B](f: A => B)(implicit r: Foldable[M], m: Monoid[B])
因此,某处必须是Foldable [List [_]]和Monoid [Int](带有append = +和零= 0)。但是我找不到这两个隐式。有找到它们的简便方法吗?
然后,下一个示例是:
List(3, 4, 5).asMA.foldMap(multiplication)
=> 60 //(3*4*5)
在这里,我变得更加困惑。我假设乘法必须用Mono = [Int]替换为append = *,零=1。但是随后f:A => B丢失了。如果我遵循乘法,那么我找不到与Monoid或函数等相关的任何东西。
sealed trait IntMultiplication extends NewType[Int]
trait NewType[X] {
val value: X
override def toString = value.toString
}
最佳答案
处理隐式时,有一些方便的编译器标志:-Xlog-implicits
,-Xprint:typer
和-Ytyper-debug
在这种情况下,您可以使用-Xprint:typer
标志查看带有已应用隐式的表达式。然后,第一个片段List(3, 4, 5).asMA.foldMap(identity)
将扩展为
scalaz.this.Scalaz.SeqMA[List, Int](immutable.this.List.apply[Int](3, 4, 5)).asMA.foldMap[Int]({
((x: Int) => scala.this.Predef.identity[Int](x))
})(scalaz.this.Foldable.ListFoldable,
scalaz.this.Monoid.monoid[Int](scalaz.this.Semigroup.IntSemigroup, scalaz.this.Zero.IntZero));
现在很明显
Monoid.monoid[Int](Semigroup.IntSemigroup, Zero.IntZero)
用于创建
Monoid[Int]
实例(带有append = +和零= 0)第二个片段
List(3, 4, 5).foldMap(multiplication)
将扩展为scalaz.this.Scalaz.SeqMA[List, Int](immutable.this.List.apply[Int](3, 4, 5)).foldMap[scalaz.IntMultiplication]({
((n: Int) => scalaz.Scalaz.multiplication(n))
})(scalaz.this.Foldable.ListFoldable,
scalaz.this.Monoid.monoid[scalaz.IntMultiplication](scalaz.this.Semigroup.IntMultiplicationSemigroup, scalaz.this.Zero.IntMultiplicationZero));
在这种情况下,
Monoid[IntMultiplication]
(带有append = *和零= 1)用作隐式参数。更新
要为您的类型创建
Monoid
,您需要在作用域中包含隐式Semigroup
和Zero
case class Foo(x: Int)
implicit def FooSemigroup: Semigroup[Foo] = semigroup((f1, f2) => Foo(f1.x + f2.x))
implicit def FooZero: Zero[Foo] = zero(Foo(0))
scala> (1 to 10) map Foo foldMap identity
res5: Foo = Foo(55)
关于scala - 隐式Monoid [Int]等在哪里实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10394932/