Reputation: 2589
So I wanted to make my own Functor
to play around with typeclassing. However I ran into a bunch of issues.
The endgoal is to be able to say something like Seq(1,2,3).fmap(2*_)
.
I came up with this trait
which all my Google searches (kind of) agree on:
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
I'm assuming there's no easy way to link the A
to the F[_]
, i.e. "F[A]
".
But I'm having serious trouble creating an implicit to connect to Seq
. Here's one try:
implicit class SeqFunctorOps[A](xs: Seq[A]) {
def fmap[B](f: A => B) = xs map f
}
But that doesn't fit into my Functor
, so let's extend it:
implicit class SeqFunctorOps[A](xs: Seq[A]) extends Functor[Seq] {
def fmap[A, B](f: A => B) = xs map f
}
But that doesn't work because in fmap[A, B]...
, the A
is a new generic type, and doesn't tie in with xs: Seq[A]
.
Is there a way to tie them in?
However, it also seems to me that implicit class
is not the way to go, considering that other online resources have pointed to using the companion object, but I just can't seem to make it work.
object Functor {
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
}
implicit class SeqFunctorOps[A](xs: Seq[A])(implicit F: Functor[Seq]) {
def fmap[B](f: A => B) = F.fmap(xs, f)
}
This kind of seems to work, but looks off.
Is there a general pattern to use when trying to do something like this?
Upvotes: 1
Views: 190
Reputation: 2589
Glory be to @drexin, this seems to be good enough:
trait Functor[F[_]] {
def fmap[A, B](r: F[A], f: A => B): F[B]
}
object Functor {
implicit def SeqFunctor: Functor[Seq] = new Functor[Seq] {
def fmap[A, B](r: Seq[A], f: A => B) = r map f
}
implicit class Ops[A, F[_]: Functor](xs: F[A]) {
def fmap[B](f: A => B) = implicitly[Functor[F]].fmap(xs, f)
}
}
Upvotes: 1