也许我遗漏了一些明显的东西,但我正在尝试清理使用 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 中已经为双射提供的函数和实例更清晰地编写它?
最佳答案
报价 Lars Hupel来自推特 in response to this question :
I have no idea what our
bimap
is or what's it supposed to do.
和:
Related: The
T
part ofBijectionT
is probably wrong. It probably needs to be rewritten to look like the Haskell version.
所以答案显然是否定的,我没有遗漏任何东西——这实际上是当前 API 中的一个缺口,可能会在 future 的 Scalaz 版本中得到修复。
关于scala - 将双射提升为仿函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19455470/