This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Functor — incompatible types

1 reply
gbalcerek@echos...
Joined: 2009-10-21,
User offline. Last seen 31 weeks 2 days ago.
 Hello, Why is the method type incompatile in the following code? How can I make it compile?   scala> trait Functor[F[_]] { def map[A,B](f:A=>B): F[B] }
defined trait Functor   scala> case class Box[T](val content:T) extends Functor[Box] {
     |   override def map[A >: T <: T,B](f:A=>B): Box[B] = Box(f(content))
     |   override def toString = "Box("+content+")"
     | }
<console>:9: error: overriding method map in trait Functor of type [A, B](f: A => B)Box[B];
 method map has incompatible type
         override def map[A >: T <: T,B](f:A=>B): Box[B] = Box(f(content))
                      ^   (using Scala 2.9.0)   Regards, Grzegorz    
Derek Williams 3
Joined: 2011-08-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Functor — incompatible types
On Mon, Dec 5, 2011 at 6:06 PM, Grzegorz Balcerek <gbalcerek@echostar.pl> wrote:
Hello, Why is the method type incompatile in the following code? How can I make it compile?   scala> trait Functor[F[_]] { def map[A,B](f:A=>B): F[B] }
defined trait Functor   scala> case class Box[T](val content:T) extends Functor[Box] {
     |   override def map[A >: T <: T,B](f:A=>B): Box[B] = Box(f(content))
     |   override def toString = "Box("+content+")"
     | }
<console>:9: error: overriding method map in trait Functor of type [A, B](f: A => B)Box[B];
 method map has incompatible type
         override def map[A >: T <: T,B](f:A=>B): Box[B] = Box(f(content))
                      ^

It is incompatible because your Functor trait states that the type A in the map method has no constraints on it. Given a Functor[Box], how would you know what A needs to be in your map method? You can't refer to the Box class for those contraints because a Functor[Box] doesn't have to be a Box. I could make another class like this:
case class NotABox[T](val content: T) extends Functor[Box] { def map[A, B](f: A => B): Box[B] = Box(f(content)) }
How about implementing it like this:
trait Functor[F[_],A] { def map[B](f:A=>B): F[B] } case class Box[T](val content:T) extends Functor[Box, T] {   def map[B](f:T=>B): Box[B] = Box(f(content))  override def toString = "Box("+content+")"}
--
Derek Williams

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland