luca
luca

Reputation: 31

Is Shapeless' type inequality buggy?

Type inequality in shapeless does not seem to be safe once type parameters enter the picture.

For example the following code compiles

def someMethod[T](in : T) = {

  implicitly[T =:!= String]

  // some operation that requires T not String could be called here
  // even though there is no guarantee that this is safe
}

val a = someMethod("abc") // here we have just proven String != String

My intuition is that the correct behavior should be a compile time error (we have generated a proof that String =!:= String)

This is not related to the =:!= operator but to all situations in which implicit conflicts are used to emulate a negation operator.

Is this really a bug or am I missing an important point?

Upvotes: 3

Views: 260

Answers (2)

Miles Sabin
Miles Sabin

Reputation: 23046

It's a bug, or at best a surprising misfeature.

Upvotes: 2

Michael Zajac
Michael Zajac

Reputation: 55569

T =:!= String needs to be an implicit argument of someMethod. We need to collect the evidence that T is not a String at the call site, otherwise it's too late. T is erased within the body of someMethod.

def someMethod[T](in : T)(implicit ev: T =:!= String) = {
  println("Definitely not a string")
}

scala> someMethod("abc")
<console>:16: error: ambiguous implicit values:
 both method neqAmbig1 in package shapeless of type [A]=> shapeless.=:!=[A,A]
 and method neqAmbig2 in package shapeless of type [A]=> shapeless.=:!=[A,A]
 match expected type shapeless.=:!=[String,String]
       someMethod("abc")
                 ^

Upvotes: 1

Related Questions