Skip to content

Instantly share code, notes, and snippets.

@djspiewak
Last active January 23, 2016 23:26
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save djspiewak/498a76ff93aa6006116f to your computer and use it in GitHub Desktop.
Save djspiewak/498a76ff93aa6006116f to your computer and use it in GitHub Desktop.
// let's imagine you have an algebra that has a constructor like the following
sealed trait Algebra[A]
case class Ext[E, A](e: E, f: E => A) extends Algebra[A]
/*
* Not at all an uncommon pattern! Basically, this is going to show up any time you're
* doing GADTs or GADT-like things, or any sort of type-aligned sequence (in any form).
* The problem is that the pattern matcher affixes types in a linear fashion, and thus
* will not unify the solution to E between the two parameters. For example:
*/
def run[A](alg: Algebra[A]): A = alg match {
case Ext(e, f) => f(e) // does not compile!
}
/*
* It doesn't compile because scalac can't figure out that the E it solved for when it
* looked at the first parameter is the same E when it comes to the second parameter.
* However, it CAN solve for the E in the enclosing Ext type, because it's not being asked
* to fix the type while it is in the process of fixing types at that level (i.e. the type
* is solely derived from an "inner" level of the pattern). For this reason, we can use
* the following workaround:
*/
def run[A](alg: Algebra[A]): A = alg match {
case a @ Ext(e, _) => a.f(e) // yay!
}
/*
* This works just fine! And it will work any time you use this sort of pattern.
*/
@gigiigig
Copy link

Which version of Scala? It seems to compile with 2.11.6.
Luigi

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