Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a type constraint with abstract type

Tags:

types

scala

Given the following code :

trait S { type T }
case class A(t: Seq[String]) extends S { type T = Seq[String] }

I don't understand this compilation error : It seems that the evidence is not used.

def f[S<:A, X](g: => Seq[X])(implicit ev: S#T =:= Seq[X]) = new A(g)

<console>:50: error: type mismatch;
 found   : Seq[X]
 required: Seq[String]
       def f[S<:A, X](g: => Seq[X])(implicit ev: S#T =:= Seq[X]) = new A(g)
like image 610
Yann Moisan Avatar asked Oct 10 '14 09:10

Yann Moisan


1 Answers

For how silly it may look, swapping the order of =:= operands solves the issue

def f[S<:A, X](g: => Seq[X])(implicit ev: Seq[X] =:= S#T) = new A(g)

Thank you, scalac.

explanation

When you say implicit ev S#T =:= Seq[X], the compiler provides an implicit conversion from S#T to Seq[X]. It doesn't however provide an equivalent conversion from Seq[X] to S#T, and that's the silly part: isn't equality supposed to be commutative?

Some extra details on the subject here: http://typelevel.org/blog/2014/07/02/type_equality_to_leibniz.html

like image 157
Gabriele Petronella Avatar answered Sep 28 '22 09:09

Gabriele Petronella