
Higher-Order Type-Level Programming in Haskell [pdf] - justinhj
https://www.microsoft.com/en-us/research/uploads/prod/2019/03/ho-haskell-5c8bb4918a4de.pdf
======
LeanderK
I think it's a major step towards more pleasant type-level programming in
haskell. I recently worked on a very type-level heavy side-project and the
matchability is a real issue.

I think this could drastically simplify the whole singletons-library and would
also enable proving stuff via induction entirly in the type-level.

------
mpoteat
I wonder if this formalism can be applied to Typescript. I occasionally come
across tricky typing problems with higher order functions like "flatten" that
this might be helpful for.

~~~
fro0116
Being somewhat of a functional programming zealot (coming from the Clojure
camp, so please excuse me if these are stupid questions, considering my lack
of familiarity with typed functional programming in general), this is
something that has always bothered me about TypeScript's type system, the poor
support for higher order functions.

For a prime example of this, take a look at the type definition for the ramda
pipe function:
[https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/ramda/index.d.ts#L1941)

It's a hard coded list of 10 signature overrides that allows it to support up
to 10 piped functions. Obviously the actual ramda pipe function can support an
arbitrary number of piped functions at runtime, but the types as written only
supports 10.

This seems awfully inelegant and inflexible. I assume there is some
fundamental deficiency in TypeScript's type system that forces people to
specify types this way, otherwise it would have been rewritten by now.

Is higher kinded types what's missing to be able to express higher order
functions and functional composition in an elegant way? If so, can someone
provide an example of what the type signature of a pipe function would look
like with higher kinded types? Any ideas if higher kinded types are being
considered as additions in future versions of TypeScript, or if that's even
feasible at all?

~~~
mjburgess
I don't think HKTs are the solution here. The problem is that functions have
curried type signatures (ie., they are typed st. all the arguments "come
together", so the arity is part of the type).

In Haskell I believe when you write fn :: a -> b

a can be inferred to be (Int -> Int -> Int), say.

Here when you write pipe<A, B>(A => B): A => B

'A => B' just means a function from one-arg A to one-arg B.

The solution is some sort of type-level function, but it also requires new
sorts of type variables.

~~~
ratmice
One can do this sort of thing in Ur i believe, which uses system F-omega with
row polymorphic types,
[http://www.impredicative.com/ur/](http://www.impredicative.com/ur/)

------
ggm
I understood about one concept in 10 here. Not all of the _and_ and _but_ were
understood btw. But, that said, it feels like this is saying something useful,
and has a formal proof quality which if correct, has a really strong
indication of a useful thing: They say up front that noting issues in
backwards compatibility this can make a very big difference to the speed of
processing inputs.

There is "famous person said so, so it must be true" in this because its hard
to contradict SPJ. I don't think I'm even in the corridor, let alone the room
of people who _could_ question the logic, but I think the rebuttal needs to be
said by somebody who could, if there is one.

Notationally I struggle to see how well people could "read" the ascii version
of this because they depended on formal logic typography to make the ->>
symbol. I don't like ::= and := and -> and ->> risks which are inherent in new
mappings into a language, and in type systems I find myself desperately
searching for the "said voice" internally which speaks the symbols as a cogent
language statement.

"is" is such a useful word. "maybe" is such a useful word. "x _is_ an Integer"
and "x _maybe is_ an Integer" are easy to understand. How would I "say" ->> to
be clear its meaning against is and maybe?

~~~
ximeng
-> could be read as type arrow and ->> as unmatchable type arrow?

~~~
ggm
can you "speak" a sentence either here written or in your head, using those
words, which feels like it makes sense?

~~~
ximeng
"As an example, the kind of Maybe remains ⋆ → ⋆, but DbType now has kind ⋆ ↠
⋆" \- the kind of Maybe remains star type arrow star, but DbType now has kind
star unmatchable type arrow star.

~~~
ggm
_unmatchable_ type or _not yet matched_ type? _dangling_ type? _provisional_
type? _unconfirmed_ type?

~~~
ximeng
Unmatchable type, following terminology from the paper. This is contrasted
with a matchable type which is "injective" and "generative". Basically these
unmatchable types are potentially ambiguous under certain operations, so it
indicates to the type system limits to the transformations which can be done.
So Maybe is * -> * means that if Maybe a is f a, then f is Maybe, and if Maybe
a is Maybe b then a is b. If another type t is * ->> *, then the type checker
can't make these assumptions.

