Подъем биекции в функтор

Может быть, я упускаю что-то очевидное, но я пытаюсь очистить некоторый шаблон в проекте, который использует 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.

Другие вопросы по тегам