HKTs plans for TypeScript [OT]


#1

Quasi-approved HKTs for TypeScript:

In approximated Rust-esque:

trait Monad<T<*>> {
    fn map<A, B>(f: &Fn(A) -> B) -> Box<Fn(T<A>) -> T<B>>;
    fn lift<A>(a: A) -> T<A>;
    fn join<A>(tta: T<T<A>>) -> T<A>;
}

trait Cartesian<T<*>> {
    fn all<A>(a: Vec<T<A>>) -> T<Vec<A>>;
}

trait Foo<T<*, *>> {
    fn bar<A, B>(f: Fn(A) -> B) -> T<A, B>;
}

Add lifetimes and the different Rust closures, and things get more “interesting” :slight_smile:


#2

Ah being able to specify a generic bound on a generic parameter would be interesting!

I wonder how it would hypothetically resolve T<*> for A where:

struct A;

impl Trait1<B> for A { }

impl Trait2<B> for A { }

I guess you could limit it on the struct definition and not traits, that example is actually a fairly flimsy argument.


#3

Maybe I’m wrong but shouldn’t topics like this go under the https://internals.rust-lang.org/c/language-design section? (I know it was marked OT but still as it may spawn more interesting discussion over there)


#4

I am sometimes shy in posting in the internals group, but you’re right. Do you know if there’s a way to move a thread there? :slight_smile:


#5

Sorry but I have no idea :slight_smile:


#6

There is not, as they’re totally separate instances.


#7

Looks like the example uses Haskell-like syntax that ignores Self and also has explicit currying, in Rust it would have to be:

trait<*> Monad {
    fn map<A, B>(f: &Fn(A) -> B, ta: Self<A>) -> Self<B>;
    fn lift<A>(a: A) -> Self<A>;
    fn join<A>(tta: Self<Self<A>>) -> Self<A>;
}

trait<*> Cartesian {
    fn all<A>(a: Vec<Self<A>>) -> Self<Vec<A>>;
}

trait<*, *> Foo {
    fn bar<A, B>(f: Fn(A) -> B) -> Self<A, B>;
}

Although a syntax like trait Monad: type<type> {...} is probably better suited for Rust.