Higher-Order Type-Level Programming in Haskell [pdf]
microsoft.com
microsoft.com
I think this could drastically simplify the whole singletons-library and would also enable proving stuff via induction entirly in the type-level.
[1] https://github.com/DefinitelyTyped/DefinitelyTyped/blob/mast...
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...
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?
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.
Like composition: `f . g . h $ a`
It adds inference for higher order functions, and, from a bit of playing with the Typescript nightly build, ramda works much better. Once 3.4 comes out it's going to make life a lot easier for ramda/functional/clojure-like programming
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?
-> is used with type constructors like Maybe or Either, and arguments passed to it can still be "read" in the result (for example, a -> Maybe a, or a -> b -> Either a b). I would call it a "slotting" arrow to connote that the argument will be fitted into a hole of a type constructor.
So I would read a -> Maybe a as "slotting a into Maybe".
While _some_ higher-kinded manipulating code needs the explicit ->> syntax to be well-typed, the authors determined that explicitly requiring it (or, likewise, the polymorphic arrow syntax ->^U) would prevent the intent of older code from changing, while the improved inferences allowed just by the new constraint kinds existing allows new flexibility.
Also: I don't think there's anything you could write in the double arrow's place that would be "readable" or "just make sense". I think it's difficult to acquire an innane "sense" for what a higher kinded operation actually _is_. By sticking close to familiar syntax, it should hopefully be easier to grasp as a related concept.