为了mzero的目的,将案例类作为产品处理

Hug*_*ugh 2 scala scalaz

使用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)

Tra*_*own 6

即使在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作为模型之后,它应该不会太难实现.