也许我遗漏了一些明显的东西,但是我正在尝试清理使用 Scalaz 7 的项目中的一些样板,并且我没有找到一个看起来非常简单且可能有用的特定拼图。
假设我们有两种类型之间的双射:
case class Foo(x: Int)
case class Bar(i: Int)
import scalaz._, Scalaz._, BijectionT._
val fb: Foo <@> Bar = bijection[Id, Id, Foo, Bar](
foo => Bar(foo.x),
bar => Foo(bar.i)
)
现在假设我们发现我们需要 和 之间的双List[Foo]
射List[Bar]
。我们可以很容易地编写一个提供此功能的隐式类(实际上我们也可以让它适用于任何函子):
implicit class BijectionLifter[A, B](val bij: A <@> B) extends AnyVal {
def liftInto[F[_]: Functor]: F[A] <@> F[B] = bijection[Id, Id, F[A], F[B]](
_ map bij.to,
_ map bij.from
)
}
请注意,这是bimap
从 Haskell 的Data.Bijection
. Scalaz 的双射也有一个名为 的方法bimap
,但它有一个更繁忙的类型,并且似乎没有以任何明显的方式做我想做的事。
现在我们可以只写以下内容:
fb.liftInto[List]
我们已经得到了我们需要的双射。
我是否遗漏了一些抽象,使我可以使用 Scalaz 7 中已经为双射提供的函数和实例更清晰地编写它?