Подъем биекции в функтор
Может быть, я упускаю что-то очевидное, но я пытаюсь очистить некоторый шаблон в проекте, который использует 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
от Хаскелла Data.Bijection
, Биекция Скалаза также имеет метод с именем bimap
, но он имеет гораздо более оживленный тип и, кажется, не делает то, что я хочу, очевидным образом.
Теперь мы можем просто написать следующее:
fb.liftInto[List]
И у нас есть биекция, в которой мы нуждаемся.
Я пропускаю некоторую абстракцию, которая позволила бы мне написать это более четко с помощью функций и экземпляров, уже предоставленных для биекций в Scalaz 7?
1 ответ
Цитирую Ларса Хупеля из Twitter в ответ на этот вопрос:
Я понятия не имею, что наши
bimap
или что он должен делать.
А также:
Связанные:
T
частьBijectionT
вероятно неправильно Вероятно, его нужно переписать так, чтобы он выглядел как версия на Haskell.
Таким образом, ответ, очевидно, нет, я ничего не упустил - на самом деле это пробел в текущем API, который, вероятно, будет исправлен в будущей версии Scalaz.