21

也许我遗漏了一些明显的东西,但是我正在尝试清理使用 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 中已经为双射提供的函数和实例更清晰地编写它?

4

1 回答 1

3

引用Twitter的Lars Hupel来回答这个问题

我不知道我们bimap是什么或它应该做什么。

和:

相关: 的T部分BijectionT可能是错误的。它可能需要重写以看起来像 Haskell 版本。

所以答案显然是否定的,我没有遗漏任何东西——这实际上是当前 API 中的一个缺口,可能会在未来的 Scalaz 版本中得到修复。

于 2013-11-19T12:40:29.630 回答