(|>) 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
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.