使用Scalaz 7,我们可以获得monoids产品的零:
scala> mzero[(Int, String)]
res13: (Int, String) = (0,"")
Run Code Online (Sandbox Code Playgroud)
是否有更简单的方法来获得其字段为幺半群的案例类的零值?理想情况下,不需要重复字段类型的方法:
scala> case class Foo(x: Int, y: String)
defined class Foo
scala> (Foo.apply _).tupled(mzero[(Int, String)])
res15: Foo = Foo(0,)
Run Code Online (Sandbox Code Playgroud)
即使在Shapeless中你也需要一些样板,如下所示:
implicit def fooIso = Iso.hlist(Foo.apply _, Foo.unapply _)
Run Code Online (Sandbox Code Playgroud)
我们可以在Scalaz 7中做类似的事情(尽管不那么优雅).首先是一些通用机械:
import scalaz._, Scalaz._, Isomorphism._
case class MonoidFromIsorphism[F, G](iso: F <=> G)(
implicit val G: Monoid[G]
) extends IsomorphismMonoid[F, G]
Run Code Online (Sandbox Code Playgroud)
现在我们可以写:
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
}
)
Run Code Online (Sandbox Code Playgroud)
哪个有效:
scala> mzero[Foo]
res0: Foo = Foo(0,)
Run Code Online (Sandbox Code Playgroud)
这种方法仍然需要你重复这些类型,并且它不仅仅比Foo手工编写实例更简洁(实际上,如果算上MonoidFromIsomorphism定义,它就不那么简洁了,但这对我来说就像真正应该的那种方便的东西一样在图书馆里).
现在缺少的是HList元组同构,使我们只是写一个简单的Foo- HList同构,就像无形的.scalaz.typelevel没有(目前)提供这种开箱即用的功能,但在Shapeless作为模型之后,它应该不会太难实现.