Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Процитировать Lars Hupel из Twitter в ответ на этот вопрос:

Я не знаю, что такое наш bimap или что он должен делать.

и

Связано: T часть BijectionT, вероятно, неверна. Вероятно, его нужно переписать так, чтобы он выглядел как версия Haskell.

Итак, ответ, по-видимому, нет, я ничего не пропустил - на самом деле это пробел в текущем API, который, вероятно, будет исправлен в будущей версии Scalaz.