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

The most common way to format code like that in F# would be something like let evenSum = [1;2;3;4] |> List.filter isEven |> List.Sum

Using |> is a win for two reasons - code flows more naturally, and the type inferencing works better. e.g. List.Map (fun d -> d.Hour) [DateTime.Now] does not compile, but [DateTime.Now] |> List.map (fun d -> d.Hour) does.




That seems odd. It seems that `arg |> func` would simply be sugar for `func arg` (or a function that accomplished this). Why are they not equivalent?


F# type inference runs left -> right, top -> bottom. In the first snippet, the lambda is encountered first, and the compiler has no knowledge of what the type of "d" is, so it can't assume d has a ".Hour" member. In the second snippet, the compiler has already seen the input list and knows it contains DateTimes, so when it encounters the lambda, "d" is known to be a DateTime and everything is groovy.


Ah, I see, thanks for that. So it's not running Hindley Milner (or at least, not unless it's quite heavily modified). That's not surprising, I guess, since it takes no small amount of effort to get HM to work in an OO/imperative setting.


|> is a low priority operator, which forces evaluation to occur first on the left.

[1; 2; 3] |> List.filter (fun a -> a < 3) |> List.sum is the same as List.sum (List.filter (fun a -> a < 3) [1; 2; 3])

arg |> func is the same as func (arg)


Yeah, that's exactly what I thought. It doesn't explain (or I don't see it yet) why the first example he gave wouldn't compile, but the second would.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

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

Search: