Question about Generic Associated Types in the Generic Manifesto

I know this has been covered ad nauseum before as HKT's etc, but I have some particular questions about this particular change. We have this directly from the manifesto:

    protocol Wrapper {
      associatedtype Wrapped<T>
      
      static func wrap<T>(_ t: T) -> Wrapped<T>
    }

    enum OptionalWrapper {
      typealias Wrapped<T> = Optional<T>
      
      static func wrap<T>(_ t: T) -> Optional<T>
    }

Note: generic associatedtypes address many use cases also addressed by higher-kinded types but with lower implementation complexity.
  1. Shouldn't OptionalWrapper conform to Wrapper?
  2. Is it the intent that I could then write separate protocols which use OptionalWrapper to produce Functor, Applicative, Monad? bc I'm not quite seeing how to do that from the description.

That's likely an oversight. A PR would be welcome.

Sure. Will try to do that soon.

so is there any reason I could not write:

    protocol Functor {
      associatedtype F<T>
      associatedtype F<U>
      
      static func fmap<T, U>(_ transform: (T) -> U) -> F<T> -> F<U> 
    }

    enum OptionalFunctor: Functor {
      typealias F<T> = Optional<T>
      typealias F<U> = Optional<U>      
      static func fmap<T, U>(_ transform: (T) -> U) -> Optional<T> -> Optional<U> {
          ...
      }
    }

'cause that would be sneaky cool :)

I think you meant to write this, because your code won't compile as is in the future.

protocol Functor {
  associatedtype F<T>
  static func fmap<T, U>(_ transform: (T) -> U) -> F<T> -> F<U> 
}

enum OptionalFunctor: Functor {
  // F<T> is inferred as Optional<T>
  static func fmap<T, U>(_ transform: (T) -> U) -> Optional<T> -> Optional<U> {
    ...
  }
}

That's interesting. I would have thought I needed at least one typealias in the implementation. Could I also add this conformance directly to Optional as an extension?

You can also write it this way:

enum OptionalFunctor: Functor {
  typealias F<T> = Optional<T>
  static func fmap<T, U>(_ transform: (T) -> U) -> F<T> -> F<U> {
    ...
  }
}

Looking at that, I can't think of any use case I have for HKTs that I can't implement. The syntax is not the most convenient, but it certainly is a huge step forward.

It really is, it requires a few intermediate steps but we will be able to cover a lot of use cases with this feature

I particularly like the inference around F in this example. It will make explaining this stuff to my students much simpler. Right now, I don't even try to explain PATs to them because there are immediately useful cases like this can't be handled. This I think would nicely simplify the task of explaining to them why Array, Range, Optional, Result and Publisher all have a map method and thereby to see patterns in generics that are hard to grasp otherwise.