Created
March 11, 2022 19:14
-
-
Save odersky/73661146f3235e71fde81c5177d6b3d1 to your computer and use it in GitHub Desktop.
This file contains 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
Here's a systematic way to remove F-bounds from your code. It's inspired by the algebraic subtyping encoding from Stephen Dolan's PhD thesis: | |
If you have an F-bounded type T <: F[T] simply replace it with T. Then everywhere T is used, replace it with T & F[T]. | |
I tested that strategy with the example from @tpolecat's blog on F-bounds. | |
Here's how it comes out: | |
trait Pet[A]: | |
this: A => | |
def name: String | |
def renamed(newName: String): A & Pet[A] | |
case class Fish(name: String, age: Int) extends Pet[Fish]: // note the type argument | |
def renamed(newName: String) = copy(name = newName) | |
def esquire[A](a: A & Pet[A]): A & Pet[A] = a.renamed(a.name + ", Esq.") | |
val a = Fish("Jimmy", 2) | |
val b = a.renamed("Bob") | |
val c = esquire(b) | |
Maybe this shows up a way how to get rid of F-bounds altogether over time? Since they are so fragile, this would be an improvement from a language design standpoint, IMO. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment