将双射提升为仿函数

Tra*_*own 21 scala functor bijection scalaz scalaz7

也许我错过了一些明显的东西,但我正在尝试清理一个使用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)
)
Run Code Online (Sandbox Code Playgroud)

现在假设我们发现我们需要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
  )
}
Run Code Online (Sandbox Code Playgroud)

请注意,这是bimapHaskell的直接翻译Data.Bijection.Scalaz的双射也有一个名为的方法bimap,但它有一个更繁忙的类型,似乎没有以任何明显的方式做我想要的.

现在我们可以写下面的内容:

fb.liftInto[List]
Run Code Online (Sandbox Code Playgroud)

我们得到了我们需要的双射.

我是否遗漏了一些抽象,这使得我可以用Scalaz 7中已经提供的用于双射的函数和实例更清晰地编写它?

Tra*_*own 3

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

\n\n
\n

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

\n
\n\n

和:

\n\n
\n

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

\n
\n\n

所以答案显然是否定的,我没有遗漏任何东西\xe2\x80\x94这实际上是当前 API 中的一个空白,可能会在未来的 Scalaz 版本中修复。

\n