Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 950
Ben Lings Avatar asked Sep 21 '09 22:09

Ben Lings


People also ask

What is the difference between function and composition?

Roughly, application ( $ ) is used between a function and its argument (a list in this case), while composition ( . ) is used between two functions. About pattern matching: in the first solution, the function reverse will perform the needed pattern match for you, so myLast does not have to.

Is Haskell right or left associative?

Nevertheless function composition in Haskell is right associative: infixr 9 .

What is higher order function in Haskell?

A higher-order function is a function that takes other functions as arguments or returns a function as result.


2 Answers

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.

like image 194
GS - Apologise to Monica Avatar answered Oct 06 '22 06:10

GS - Apologise to Monica


I am being a little speculative...

Culture: I think |> is an important operator in the F# "culture", and perhaps similarly with . for Haskell. F# has a function composition operator << but I think the F# community tends to use points-free style less than the Haskell community.

Language differences: I don't know enough about both languages to compare, but perhaps the rules for generalizing let-bindings are sufficiently different as to affect this. For example, I know in F# sometimes writing

let f = exp 

will not compile, and you need explicit eta-conversion:

let f x = (exp) x   // or x |> exp 

to make it compile. This also steers people away from points-free/compositional style, and towards the pipelining style. Also, F# type inference sometimes demands pipelining, so that a known type appears on the left (see here).

(Personally, I find points-free style unreadable, but I suppose every new/different thing seems unreadable until you become accustomed to it.)

I think both are potentially viable in either language, and history/culture/accident may define why each community settled at a different "attractor".

like image 42
Brian Avatar answered Oct 06 '22 08:10

Brian