In F#, use of the the pipe-forward operator, |>
, is pretty common. However, in Haskell I've only ever seen function composition, (.)
, being used. I understand that they are related, but is there a language reason that pipe-forward isn't used in Haskell or is it something else?
In F# (|>)
is important because of the left-to-right typechecking. For example:
List.map (fun x -> x.Value) xs
generally won't typecheck, because even if the type of xs
is known, the type of the argument x
to the lambda isn't known at the time the typechecker sees it, so it doesn't know how to resolve x.Value
.
In contrast
xs |> List.map (fun x -> x.Value)
will work fine, because the type of xs
will lead to the type of x
being known.
The left-to-right typechecking is required because of the name resolution involved in constructs like x.Value
. Simon Peyton Jones has written a proposal for adding a similar kind of name resolution to Haskell, but he suggests using local constraints to track whether a type supports a particular operation or not, instead. So in the first sample the requirement that x
needs a Value
property would be carried forward until xs
was seen and this requirement could be resolved. This does complicate the type system, though.