也许我遗漏了一些显而易见的东西,但我试图在一个使用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
)
}请注意,这是从Haskell的bimap的Data.Bijection中直接翻译出来的。Scalaz的bijection也有一个名为bimap的方法,但是它有一个更繁忙的类型,而且似乎没有以任何明显的方式完成我想做的事情。
现在,我们只需编写以下内容:
fb.liftInto[List]我们得到了我们需要的双射。
我是不是缺少了一些抽象,这样我就可以用Scalaz 7中已经为双射提供的函数和实例更清晰地编写它了吗?
https://stackoverflow.com/questions/19455470
复制相似问题