Srinivas
Srinivas

Reputation: 2098

Implementing Higher kinded types in scala via case class

Let's say I want to implement a map for Seq.

trait Functor2[F[_]] {
  def map1[A,B](fa : F[A])(func: A => B) : F[B]
}

case class SeqFunctor1[A](fa: Seq[A]) extends Functor2[Seq] {
  override def map1[A, B](fa: Seq[A])(func: A => B) : Seq[B] = fa map func
}

I can call this via

val list = List(1,2,3,4)
val f1 : Int => Int = (i : Int) => i * 10
SeqFunctor1(list).map1(list)(f1).

I do not like the fact that I have to use list twice. So I try this

trait Functor3[F[_]] {
  def map1[A,B](func: A => B) : F[B]
}

case class SeqFunctor2[A](fa: Seq[A]) extends Functor3[Seq] {
  override def map1[A, B](func: A => B) : Seq[B] = fa map func
}

so that I can use it via this

SeqFunctor2(list).map1(f1)

I get this error

Error:(45, 59) type mismatch;
 found   : A(in method map1) => B
 required: A(in class SeqFunctor2) => ?
  override def map1[A, B](func: A => B) : Seq[B] = fa map func

I know you can implement it via an object, but it would be nice to know how to use this via case class (and also a better way of doing it than the one that works).

Upvotes: 0

Views: 120

Answers (1)

Dominic Egger
Dominic Egger

Reputation: 1016

You are shadowing your A in the case class definition with the one of your map definition. You could do this:

trait Functor3[F[_], A] {
  def map1[B](func: A => B) : F[B]
}

case class SeqFunctor2[A](fa: Seq[A]) extends Functor3[Seq, A] {
  override def map1[B](func: A => B) : Seq[B] = fa map func
}

val list = List(1,2,3,4)
val f1 : Int => Int = (i : Int) => i * 10

SeqFunctor2(list).map1(f1)

But why do you want to have your Functor as a case class? you really only need one instance of it.

Upvotes: 3

Related Questions