Haskell composition (.) vs F#'s pipe forward operator (|>)

Ben Lings picture Ben Lings · Sep 22, 2009 · Viewed 22.2k times · Source

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?

Answer

GS - Apologise to Monica picture GS - Apologise to Monica · Sep 22, 2009

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.