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
定義を数えるとそれほど簡潔ではありませんが、それは本当に必要な便利な種類のもののように感じます)図書館にいる)。
欠けているのは、HList
Shapeless のように単純な同型を書けるタプル同型Foo
ですHList
。scalaz.typelevel
は (現在) これをそのまま提供していませんが、モデルとして Shapeless に従っているため、実装するのはそれほど難しくありません。