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?
相关问题
- F#: Storing and mapping a list of functions
- Understanding do notation for simple Reader monad:
- Making Custom Instances of PersistBackend
- Haskell: What is the differrence between `Num [a]
- applying a list to an entered function to check fo
相关文章
- Is it possible to write pattern-matched functions
- Haskell underscore vs. explicit variable
- Is there something like the threading macro from C
- Top-level expression evaluation at compile time
- FSharp.Data.JsonProvider - Getting json from types
- Stuck in the State Monad
- Signing an F# Assembly (Strong name component)
- Learning F#: What books using other programming la
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
will not compile, and you need explicit eta-conversion:
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".
This is my first day to try Haskell (after Rust and F#), and I was able to define F#'s |> operator:
and it seems to work:
I bet a Haskell expert can give you an even better solution.
In F#
(|>)
is important because of the left-to-right typechecking. For example:generally won't typecheck, because even if the type of
xs
is known, the type of the argumentx
to the lambda isn't known at the time the typechecker sees it, so it doesn't know how to resolvex.Value
.In contrast
will work fine, because the type of
xs
will lead to the type ofx
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 thatx
needs aValue
property would be carried forward untilxs
was seen and this requirement could be resolved. This does complicate the type system, though.I have seen
>>>
being used forflip (.)
, and I often use that myself, especially for long chains that are best understood left-to-right.>>>
is actually from Control.Arrow, and works on more than just functions.Aside from style and culture, this boils down to optimizing the language design for either pure or impure code.
The
|>
operator is common in F# largely because it helps to hide two limitations that appear with predominantly-impure code:Note that the former limitation does not exist in OCaml because subtyping is structural instead of nominal, so the structural type is easily refined via unification as type inference progresses.
Haskell takes a different trade-off, choosing to focus on predominantly-pure code where these limitations can be lifted.
I think we're confusing things. Haskell's (
.
) is equivalent to F#'s (>>
). Not to be confused with F#'s (|>
) which is just inverted function application and is like Haskell's ($
) - reversed:I believe Haskell programmers do use
$
often. Perhaps not as often as F# programmers tend to use|>
. On the other hand, some F# guys use>>
to a ridiculous degree: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspx