也许我错过了一些明显的东西,但我正在尝试清理一个使用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 Data.Bijection
的bimap
的直接翻译。 Scalaz的双射也有一个名为bimap
的方法,但它有一个更繁忙的类型,似乎没有以任何明显的方式做我想要的。
现在我们可以写下以下内容:
fb.liftInto[List]
我们得到了我们需要的双射。
我是否遗漏了一些抽象概念,这使我能够更加干净地编写Scalaz 7中已经提供的用于双射的函数和实例?
答案 0 :(得分:3)
引用Twitter Lars Hupel中的in response to this question:
我不知道我们的
bimap
是什么或它应该做什么。
和
相关:
T
的{{1}}部分可能不对。它可能需要重写为看起来像Haskell版本。
所以答案显然不是,我没有遗漏任何东西 - 这实际上是当前API的一个空白,可能会在未来的Scalaz版本中修复。