I am dipping my toes in higher kinded types, exploring a very basic Scala example:
trait Mappable[F[_]] {
def map[A, B](fa: F[A])(f: A => B): F[B]
}
object Mappable {
implicit object MappableOption extends Mappable[Option] {
def map[A, B](fa: Option[A])(f: A => B): Option[B] = fa.map(f)
}
implicit object MappableSeq extends Mappable[Seq] {
def map[A, B](fa: Seq[A])(f: A => B): Seq[B] = fa.map(f)
}
}
def bananaTuple[F[_], T](f: F[T])(implicit F: Mappable[F]): F[(String, T)] =
F.map(f)(("banana", _))
This works:
bananaTuple(Option(42)) // Some((banana,42))
bananaTuple(Seq(42)) // List((banana,42))
But this does not compile:
bananaTuple(Some(42))
bananaTuple(List(42))
The compile errors I get:
could not find implicit value for parameter F: ch.netzwerg.hkt.HigherKindedTypes.Mappable[Some] bananaTuple(Some(42))
not enough arguments for method bananaTuple: (implicit F: ch.netzwerg.hkt.HigherKindedTypes.Mappable[Some])Some[(String, Int)]. Unspecified value parameter F. bananaTuple(Some(42))
How can I bring variance into the game?