Scala 隐式幺半群[Int]等在哪里实现
我试着学习/理解一点scalaz。为此,我从以下示例开始:Scala 隐式幺半群[Int]等在哪里实现,scala,scalaz,Scala,Scalaz,我试着学习/理解一点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]) 所以某个地方必须有一个可折叠的[List[]]和一个幺半群[Int](append=+和zero=0)。但我没能找到这两个。有没有找到它们的简单方法 下一个例子是: List(3,
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])
所以某个地方必须有一个可折叠的[List[]]和一个幺半群[Int](append=+和zero=0)。但我没能找到这两个。有没有找到它们的简单方法
下一个例子是:
List(3, 4, 5).asMA.foldMap(multiplication)
=> 60 //(3*4*5)
在这里,我更加困惑。我假设乘法必须将幺半群[Int]替换为一个append=*,zero=1。但是f:A=>B丢失了。如果我遵循乘法,我找不到任何与幺半群或函数等有关的东西
sealed trait IntMultiplication extends NewType[Int]
trait NewType[X] {
val value: X
override def toString = value.toString
}
Scalaz6将typeclass实例存储在typeclass本身的伴生对象中,因此您需要查看这里 在Monoid[T]的情况下,实际的typeclass可分为两部分:半群[T]为我们提供了追加操作(T,T)=>T,零[T]为我们提供了一个零函数:()=>T。然后,实际的Monoid实例可以通过MonoidLow中的隐式def Monoid生成 对于foldable,foldable[List]的typeclass位于可折叠单例中,称为ListFoldable 我确信您已经解决了,整数范围内的默认幺半群是(+,0),因此您在第二个示例中使用的乘法函数只是包装器类型intmultiply的转换器,它在相关的伴随对象中定义了半群和零实例 如果你想了解Scalaz,这里有几段很好的介绍视频。我发现最有用的是以下两个: [1] [2]
两者都涉及幺半群。在处理隐式时,有一些方便的编译器标志:
-Xlog implicits
,-Xprint:typer
和-Ytyper debug
在这种情况下,您可以使用-Xprint:typer
标志查看应用了隐式的表达式。然后,第一个片段列表(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));
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.monoid[Int](Semigroup.IntSemigroup, Zero.IntZero)
用于创建Monoid[Int]
实例(带append=+和zero=0)
第二个代码段,List(3,4,5)。foldMap(乘法)
将扩展到
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));
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[intmultiply]
(带append=*和zero=1)用作隐式参数
更新
要为您的类型创建幺半群
,您需要在作用域中包含隐式半群
和零
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)
实际上,我的例子来自视频[2],我试图理解当我想为我拥有的类型添加一个幺半群时会发生什么。对于零和半群,我只需要一个隐式def?是的,在范围中需要隐式
Semigroup[YourType]
和Zero[YourType]