Enforce type difference

I have a simpler solution, which also leverages ambiguity,

trait =!=[A, B]

implicit def neq[A, B] : A =!= B = null

// This pair excludes the A =:= B case
implicit def neqAmbig1[A] : A =!= A = null
implicit def neqAmbig2[A] : A =!= A = null

The original use case,

case class Foo[A,B](a : A, b : B)(implicit ev: A =!= B)
new Foo(1, "1")
new Foo("foo", Some("foo"))

// These don't compile
// new Foo(1, 1)
// new Foo("foo", "foo")
// new Foo(Some("foo"), Some("foo"))

Update

We can relate this to my "magical typesystem tricks" (thanks @jpp ;-) as follows,

type ¬[T] = T => Nothing
implicit def neg[T, U](t : T)(implicit ev : T =!= U) : ¬[U] = null

def notString[T <% ¬[String]](t : T) = t

Sample REPL session,

scala> val ns1 = notString(1)
ns1: Int = 1

scala> val ns2 = notString(1.0)
ns2: Double = 1.0

scala> val ns3 = notString(Some("foo"))
ns3: Some[java.lang.String] = Some(foo)

scala> val ns4 = notString("foo")
<console>:14: error: No implicit view available from 
  java.lang.String => (String) => Nothing.
       val ns4 = notString2("foo")
                            ^

Riffing off of Jean-Philippe's ideas, this works:

sealed class =!=[A,B]

trait LowerPriorityImplicits {
  implicit def equal[A]: =!=[A, A] = sys.error("should not be called")
}
object =!= extends LowerPriorityImplicits {
  implicit def nequal[A,B](implicit same: A =:= B = null): =!=[A,B] = 
    if (same != null) sys.error("should not be called explicitly with same type")
    else new =!=[A,B]
}     

case class Foo[A,B](a: A, b: B)(implicit e: A =!= B)

Then:

// compiles:
Foo(1f, 1.0)
Foo("", 1.0)
Foo("", 1)
Foo("Fish", Some("Fish"))

// doesn't compile
// Foo(1f, 1f)
// Foo("", "")

I'd probably simplify this as follows, since the checks for "cheating" can always be circumvented anyway (e.g. Foo(1, 1)(null) or =!=.nequal(null)):

sealed class =!=[A,B]

trait LowerPriorityImplicits {
  /** do not call explicitly! */
  implicit def equal[A]: =!=[A, A] = sys.error("should not be called")
}
object =!= extends LowerPriorityImplicits {
  /** do not call explicitly! */
  implicit def nequal[A,B]: =!=[A,B] = new =!=[A,B]
}