News for hackers. Stuff that matters.
Re:Background: how we got the generics we have (2020) by still_grokking on Saturday April 03, 2021 @01:42AM (#26678666)
Indeed, without a type-class constraint on the type constructor this isn't useful at all.

Something like the following Scala 3 code is closer to the actual intend, I think:

  @main def entryPoint =
  
    trait ConsoleLogger[W[_]]:
      extension[E] (w: W[E]) def log(): Unit

    given ConsoleLogger[List] with
      extension[A] (list: List[A]) def log() = println(list)

    given ConsoleLogger[Some] with
      extension[A] (some: Some[A]) def log() = println(some)

    def process[E, L[_] : ConsoleLogger](input: L[E]): Unit =
      input.log()

    process(List(23))
    process(Some("'process' is generic!"))
    //process(None) // Does not compile — even Some and None are interchangeable under subtype polymorphism
Here process(input) can work with any wrapped input as long as a ConsoleLogger instance is given for a specific wrapper type. The point is: There doesn't need to be any relation between the wrapper types (like in the example with List and Option.Some), only the "shape" needs to match W[_] (which could be actually also adapted with type lambdas in case it doesn't match, but not going into this here).

There are no comments on this comment yet.