Live data from Hacker News

Free-types: Higher kinded types in TypeScript

github.com

11–20 of 51 posts

Re: Free-types: Higher kinded types in TypeScript

#11

I wonder if there is any relationship between HKT and C#/Rust generics, from my perspective I always see HKT as "A type that accepts types that generates another type" and generic as "A functor that accepts types that generates another type". That makes me wonder if types and functors are exchangable.

For Rust, pre-GAT, there was no way to “output” a type which could be “called” with further arguments (very fuzzy terminology, sorry, best I can do!) or maybe in other words, you could write functions which retuned values, but not new functions.

Nowadays, GATs support a bigger subset of HKTs, but still not everything as I understand it.

https://blog.rust-lang.org/2022/10/28/gats-stabilization.htm...

Re: Free-types: Higher kinded types in TypeScript

#12
I'm reasonably proficient in Typescript although I wouldn't call myself an expert in type systems. But I'm not a beginner either.

However, I read though the readme and I have no idea what the usefulness of this is. Can anyone explain, in simple terms, some practical use cases for this?

Re: Free-types: Higher kinded types in TypeScript

#13

Why

A simple example I could recall from the other day is something like this:

  export type LinkedWorksheetsRecord = Record>;
  export type LinkedWorksheetsMap = Map>;
What I would rather have written instead is however something like this:

  export type LinkedWorksheets = T>;
  ...
  const myMap: LinkedWorksheets = ...;
This is however not possible, because `Map` is a type constructor which expects two more type arguments `K, V` until it is a fully applied, concrete type `Map`.

With a library like this, this is probably possible (unless I've missed something which wouldn't surprise me). It would unfortunately surely be more verbose.

Still, I would be against pulling in a dependency only for something like this. The above example is simple I believe, but not exactly a "killer-app". And no, Monads aren't either (if you don't limit effects and don't have do-notation) :P

Re: Free-types: Higher kinded types in TypeScript

#14
post #8
post #2

I’d love to be able to do dependent types in TS. Does this make that possible?

Might be wrong here, but I'm of the understanding that a dependent type system is undecidable, and so to have static dependent types you need to have a more restricted language, like the inability to write arbitrarily recursive functions. In short I don't think so but I'd also love a good explanation as to why I'm wrong.

A fully-featured dependent type system may be undecidable, but that doesn't mean you can't make one - it just means that there will be valid programs that the type checker nevertheless rejects, or there will be valid programs for which the type checker never terminates. It doesn't stop you from creating a type checker in the first place; it just weakens the guarantees you can make about that type checker.

The Typescript type checker is (or at least was) already Turing-complete (https://github.com/microsoft/TypeScript/issues/14833) without fully supporting dependent types.

Re: Free-types: Higher kinded types in TypeScript

#15

I wonder if there is any relationship between HKT and C#/Rust generics, from my perspective I always see HKT as "A type that accepts types that generates another type" and generic as "A functor that accepts types that generates another type". That makes me wonder if types and functors are exchangable.

It's easier to make the parallel between type-level and value-level reasoning.

1 is a value, and int is a concrete type.

function increment(x) { return x + 1 } is a value-level function. You feed it a value x and you get a value back. List is a type-level function: you give it a concrete type T, you get another type back.

function applyTwice(f, x) { return f(f(x)) } is a higher-order function that takes a functions as an input. A higher-kinded type is a higher-order type function.

As a concrete example, consider this pseudo-Java method:

    List map(Function fn, List as) { ... }
You take a list, and you return a list. Thing is, Java has several list implementations: LinkedList, ArrayList, CopyOnWriteArrayList, and a few others. What I'd like to express is that whatever concrete list type goes in is also the concrete type that comes out. If java allowed it, you could express it like this:

    L map extends List,A,B>(Function fn, L as) { ... }

This map is generic on L, A, and B, but also L is itself generic, so map is "twice-generic", if you will.

Re: Free-types: Higher kinded types in TypeScript

#16
post #13

Why

A simple example I could recall from the other day is something like this: export type LinkedWorksheetsRecord = Record >; export type LinkedWorksheetsMap = Map >; What I would rather have written instead is however something like this: export type LinkedWorksheets = T >; ... const myMap: LinkedWorksheets = ...; This is however not possible, because `Map` is a type constructor which expects two more type arguments `K,…

Not really possible, because Record and Map aren't compatible at all. At best they both have something like `toString`. You'll need to define at least something like RecordFunctor and MapFunctor to make this useful.

Re: Free-types: Higher kinded types in TypeScript

#17

I'm reasonably proficient in Typescript although I wouldn't call myself an expert in type systems. But I'm not a beginner either. However, I read though the readme and I have no idea what the usefulness of this is. Can anyone explain, in simple terms, some practical use cases for this?

The thing is, it takes a bit of experience to appreciate why HKT are important, and typically you can only get this experience using Haskell.

There’s a couple of ways to think about it: it gives you a way to talk about List rather than List of T, it enables you to write partial types like partially-applied functions, or it makes it possible to define Monads.

But as I say, none of these things will sound immediately useful unless you have experience of using those concepts already.

Re: Free-types: Higher kinded types in TypeScript

#19
post #2

I’d love to be able to do dependent types in TS. Does this make that possible?

No. Typescript cannot access runtime values (I assume you mean types that depend on runtime values). In TypeScript types can depend on other types and it does support literal types which covers a lot of use cases. What do you need dependent types for? [Edit: why the down vote?]

[deleted]

Re: Free-types: Higher kinded types in TypeScript

#20
post #16
post #13

Earlier quoted context omitted.

A simple example I could recall from the other day is something like this: export type LinkedWorksheetsRecord = Record >; export type LinkedWorksheetsMap = Map >; What I would rather have written instead is however something like this: export type LinkedWorksheets = T >; ... const myMap: LinkedWorksheets = ...; This is however not possible, because `Map` is a type constructor which expects two more type arguments `K,…

Not really possible, because Record and Map aren't compatible at all. At best they both have something like `toString`. You'll need to define at least something like RecordFunctor and MapFunctor to make this useful.

Only if you want to abstract over them at usage-site.

In my case I only ever used the concrete types and converted between them at some point.

Post reply on HN