Out of curiosity, what languages have type systems that can accomplish the "typed pipe" described in the article? There are plenty where you can specify a fixed number of arguments like (A -> B, B -> C), but how do you do that in a variadic context?
Sorry, I just realized that the pseudo-notation I was using to represent a partial type signature is similar to the actual type signature notation that Haskell and Elm use, so that's probably confusing things.
What I specifically meant by "(A -> B, B -> C)" was "two arguments, each of which are unary functions, and the type of the argument accepted by the second function is the same as the the return type of the first function." I think in formal notation, the full signature would be "(a -> b) -> (b -> c) -> (a -> c)" but I'm not overly familiar with that notation so I may have gotten that wrong.
The goal here is to be able to describe a function as mentioned in the article, that can accept any number of functions (either as varargs or a single list of functions), and ensure that the input of each provided function has the same type as the output of the function that precedes it.
Haskell can do this, although it's pretty unidiomatic:
data AlignedFunctionList a b where
Identity :: AlignedFunctionList x x
Pipe :: (x -> y) -> AlignedFunctionList y z -> AlignedFunctionList x z
pipe :: AlignedFunctionList a b -> (a -> b)
pipe Identity a = a
pipe (Pipe f g) a = pipe g (f a)
I must be missing something, but in Haskell this “typed pipe” (which is just reverse application) already exists in the base package as Data.Function.&.
You can write a type aligned list of functions datastructure in any language with generics and some form of interface, the same way you'd write a cons list. (To write a generic version of it you need HKTs, but with the type fixed to -> that's not an issue)