Lifting a bijection into a functor
Asked Answered
E

1

20

Maybe I'm missing something obvious, but I'm trying to clean up some boilerplate in a project that uses Scalaz 7, and I'm not finding one particular puzzle piece that seems pretty simple and possibly useful.

Suppose we have a bijection between two types:

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)
)

Now suppose we find that we need a bijection between List[Foo] and List[Bar]. We can easily write an implicit class that provides this functionality (in fact we may as well make it work for any functor):

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
  )
}

Note that this is a straightforward translation of bimap from Haskell's Data.Bijection. Scalaz's bijection also has a method named bimap, but it has a much busier type and doesn't seem to do what I want in any obvious way.

Now we can just write the following:

fb.liftInto[List]

And we've got the bijection we need.

Am I missing some abstraction that would make it possible for me to write this more cleanly with the functions and instances already provided for bijections in Scalaz 7?

Endometrium answered 18/10, 2013 at 17:18 Comment(0)
E
3

To quote Lars Hupel from Twitter in response to this question:

I have no idea what our bimap is or what's it supposed to do.

And:

Related: The T part of BijectionT is probably wrong. It probably needs to be rewritten to look like the Haskell version.

So the answer is apparently no, I wasn't missing anything—this actually is a gap in the current API that will probably be fixed in a future Scalaz version.

Endometrium answered 19/11, 2013 at 12:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.