9

私は少しの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=+およびzero=0)が必要です。しかし、私はこれら2つの暗黙を見つけることができませんでした。それらを見つける簡単な方法はありますか?

次の例は次のとおりです。

List(3, 4, 5).asMA.foldMap(multiplication)
 => 60 //(3*4*5)

ここで私はさらに混乱します。乗算は、Monoid[Int]をappend= *、zero = 1の1に置き換える必要があると想定しました。しかし、f:A=>Bがありません。そして、掛け算をたどると、モノイドや関数などに関連するものは何も見つかりません。

sealed trait IntMultiplication extends NewType[Int]

trait NewType[X] {
  val value: X
  override def toString = value.toString
}
4

2 に答える 2

9

暗黙的な処理を行う場合、いくつかの便利なコンパイラフラグがあります:-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=+およびzero=0)

2番目のスニペットは、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=*およびzero=1の場合)、暗黙のパラメーターとして使用されます。

アップデート

タイプに合わせて作成するには、暗黙的でスコープ内にMonoidある必要がありますSemigroupZero

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)
于 2012-05-01T09:20:37.530 に答える
7

Scalaz 6は、型クラスインスタンスを型クラス自体のコンパニオンオブジェクトに格納するため、そこを確認する必要があります。

Monoid [T]の場合、実際の型クラスは2つのセクションに分割できます。Semigroup[T]は追加操作(T、T)=> Tを提供し、Zero[T]はゼロ関数を提供します:() => T.実際のMonoidインスタンスは、MonoidLow内にある暗黙のdefmonoidを介して生成できます。

foldableの場合、Foldable [List]の型クラスはFoldableシングルトン内にあり、ListFoldableと呼ばれます。

確かに、整数のスコープのデフォルトのモノイドは(+、0)であるため、2番目の例で使用した乗算関数は、半群を持つラッパータイプIntMultiplicationへのコンバーターにすぎません。関連するコンパニオンオブジェクト内で定義されたゼロインスタンス。

Scalazに頭を悩ませようとしているのであれば、いくつかの優れた紹介ビデオがあります。私が最も有用だと思ったのは、次の2つです。

[1] http://skillsmatter.com/podcast/scala/practical-scalaz-2518/js-1603

[2] http://www.infoq.com/presentations/Scalaz-Functional-Programming-in-Scala#.T0q_hgmiJbw.wordpress

どちらもモノイドに触れています。

于 2012-05-01T09:11:52.887 に答える