Created
May 11, 2017 06:40
-
-
Save hamishdickson/a23550ced19283bb5a6d3f2846a3dcd4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package playing | |
/* | |
example of f-bounded polymorphism | |
*/ | |
object Playing { | |
trait A[T <: Foo[_]] { | |
type O | |
def f(t: T): O | |
} | |
// note, these have to be declared *before* the ADT otherwise it won't compile | |
implicit val barA = new A[Bar] { | |
type O = StringLimit | |
def f(t: Bar): O = StringLimit(t.s) | |
} | |
// note, if you don't have an implementation of A for everything in your ADT then you get a compilation error :) | |
/* | |
[info] Compiling 1 Scala source to /Users/hamishdickson/Programming/scala-stuff/holiday-type-playing/target/scala-2.12/classes... | |
[error] /Users/hamishdickson/Programming/scala-stuff/holiday-type-playing/Playing.scala:22: could not find implicit value for parameter evidence: playing.A[playing.Playing.Baz] | |
[error] final case class Baz(i: Int) extends Foo[Baz] | |
[error] ^ | |
[error] one error found | |
[error] (compile:compileIncremental) Compilation failed | |
[error] Total time: 0 s, completed 21-Apr-2017 17:08:46 | |
*/ | |
implicit val bazA = new A[Baz] { | |
type O = IntLimit | |
def f(t: Baz): O = IntLimit(t.i) | |
} | |
// f-bounded polymorphism | |
// note, a trait won't compile here | |
sealed abstract class Foo[B <: Foo[B]](implicit val evidence: A[B]) { | |
def fu(b: B) = implicitly[A[B]].f(b) | |
} | |
final case class Bar(s: String) extends Foo[Bar] | |
final case class Baz(i: Int) extends Foo[Baz] | |
/* | |
this no compile (which is what I want - it's not a subtype of Foo) | |
> compile | |
[info] Compiling 1 Scala source to /Users/hamishdickson/Programming/scala-stuff/holiday-type-playing/target/scala-2.12/classes... | |
[error] /Users/hamishdickson/Programming/scala-stuff/holiday-type-playing/Playing.scala:25: type arguments [playing.Playing.Woozle] do not conform to trait A's type parameter bounds [T <: playing.Playing.Foo] | |
[error] implicit val woozleA = new A[Woozle] { | |
[error] ^ | |
[error] /Users/hamishdickson/Programming/scala-stuff/holiday-type-playing/Playing.scala:25: type arguments [playing.Playing.Woozle] do not conform to trait A's type parameter bounds [T <: playing.Playing.Foo] | |
[error] implicit val woozleA = new A[Woozle] { | |
[error] ^ | |
[error] two errors found | |
[error] (compile:compileIncremental) Compilation failed | |
[error] Total time: 0 s, completed 20-Apr-2017 12:47:06 | |
case class Woozle(d: Double) | |
implicit val woozleA = new A[Woozle] { | |
type O = Double | |
def f(t: Woozle): O = t.d | |
} | |
*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment