也許我錯過了一些很明顯的東西,但是我試圖在使用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
一個簡單的翻譯。斯卡拉茲的雙射也有一個名爲bimap
的方法,但它有一個更繁忙的類型,似乎並沒有做任何我想要的任何明顯的方式。
現在我們可以只寫:
fb.liftInto[List]
而且我們已經得到了我們需要的雙射。
我是否錯過了一些抽象概念,使我可以更加乾淨地編寫Scalaz 7中已經提供的雙射對象的函數和實例?