2

Scalaz 7 では、モノイドの積のゼロを取得できます。

scala> mzero[(Int, String)]
res13: (Int, String) = (0,"")

フィールドがモノイドであるケースクラスのゼロを取得する簡単な方法はありますか? 理想的には、次のようにフィールドの型を繰り返す必要がないものです。

scala> case class Foo(x: Int, y: String)
defined class Foo
scala> (Foo.apply _).tupled(mzero[(Int, String)])
res15: Foo = Foo(0,)
4

2 に答える 2

6

Shapeless でも、次のようなボイラープレートが必要になります。

implicit def fooIso = Iso.hlist(Foo.apply _, Foo.unapply _)

Scalaz 7 でも同様のことができます (ただし、エレガントさには劣ります)。まず、いくつかの一般的な機械について:

import scalaz._, Scalaz._, Isomorphism._

case class MonoidFromIsorphism[F, G](iso: F <=> G)(
  implicit val G: Monoid[G]
) extends IsomorphismMonoid[F, G]

これで、次のように記述できます。

case class Foo(x: Int, y: String)

implicit object fooMonoid extends MonoidFromIsorphism(
  new IsoSet[Foo, (Int, String)] {
    def to = (Foo.unapply _) andThen (_.get)
    def from = (Foo.apply _).tupled
  }
)

どちらが機能しますか:

scala> mzero[Foo]
res0: Foo = Foo(0,)

このアプローチでも型を繰り返す必要があり、インスタンスを手で書き出すよりもはるかに簡潔ではありませんFoo(実際、MonoidFromIsomorphism定義を数えるとそれほど簡潔ではありませんが、それは本当に必要な便利な種類のもののように感じます)図書館にいる)。

欠けているのは、HListShapeless のように単純な同型を書けるタプル同型FooですHListscalaz.typelevelは (現在) これをそのまま提供していませんが、モデルとして Shapeless に従っているため、実装するのはそれほど難しくありません。

于 2012-11-13T11:51:16.060 に答える
1

モノイドを定義できます。

implicit val fooMonoid = new Monoid[Foo] {
  def zero = Foo(mzero[Int], mzero[String])
  def append(f1: Foo, f2: => Foo) = Foo(Monoid[Int].append(f1.x,f2.x), Monoid[String].append(f1.y,f2.y))
}

impl を記述するにはもっと良い方法があるかもしれませんが、それが基本的な考え方です。

マクロを使用して、一般的なケース クラスに対して定義できると思います。

于 2012-11-13T05:34:38.597 に答える