Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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?


If the type of C is a type D -> E -> F... then you're already there.

Or I'm misunderstanding the question. (In which case, please, somebody correct me.)

But if I'm not... Elm, Haskell, F#, and probably most other FP langs support this.


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.&.

  (&) :: a -> (a -> b) -> b


> that can accept any number of functions

So, `(a -> b) -> (b -> c) -> (c -> d) -> ... -> a -> z`.


Ah, right. In that case I suppose you'd want some kind of fold.


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)


You can actually accomplish this in Typescript, I linked a blog post in one of my other comments.

The key is mapping through all of the arguments and enforcing that argument N's output is a subtype of argument N+1's input.


C++ can do it with variadic template overloading.

https://stackoverflow.com/questions/35959979/functional-comp...


If the pipe is simple sugar then it trivial to fit into a type system.

    let x |> f  = f x


Typed Racket, but you'd write the pipe operator as a trivial macro rather than as a function.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: