Skip to content

Instantly share code, notes, and snippets.

@odersky
Created March 11, 2022 19:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odersky/73661146f3235e71fde81c5177d6b3d1 to your computer and use it in GitHub Desktop.
Save odersky/73661146f3235e71fde81c5177d6b3d1 to your computer and use it in GitHub Desktop.
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