Skip to content

Instantly share code, notes, and snippets.

@johnynek
Last active August 29, 2015 14:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save johnynek/8d315ea291bb1d553e9a to your computer and use it in GitHub Desktop.
Save johnynek/8d315ea291bb1d553e9a to your computer and use it in GitHub Desktop.
type inference with cases. Why does this fail in scala 2.10.4? Is my logic wrong, or is the compiler not smart enough?
sealed trait Key {
type Inner
}
trait IntKey extends Key {
type Inner = Int
}
trait StringKey extends Key {
type Inner = String
}
// This should compile
object Key {
def work(m: Key): m.Inner = m match {
case i: IntKey => 1 //m in IntKey, and IntKey.Inner is Int, so we are good, right?
case s: StringKey => "1"
}
}
/* in scala 2.10.4 I see this:
test.scala:28: error: type mismatch;
found : Int(1)
required: m.Inner
case i: IntKey => 1
^
test.scala:29: error: type mismatch;
found : String("1")
required: m.Inner
case s: StringKey => "1"
*/
@adriaanm
Copy link

The compiler doesn't track knowledge about the type members in terms of the matched case.

It works if you use type parameters. It would be nice to make this work for your equivalent example.

sealed trait Key[Inner] { type V = Inner }

class IntKey extends Key[Int]
class StringKey extends Key[String]

// This should compile
object Key {
  def work[K <: Key[V], V](m: K): V = m match {
   case i: IntKey => 1 //m in IntKey, and IntKey.Inner is Int, so we are good, right?
   case s: StringKey => "1"
  }
}

@johnynek
Copy link
Author

When I've really leaned on the type system in scala, this failure to consider information implied by the case match has often resulted in me adding casts that can never fail. My fear is always that I, or someone else, will get it wrong as to whether a cast is really safe or not.

I would love case matches to be factored into the type inference.

@adriaanm
Copy link

I agree completely, and expect this will be improved in 3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment