Haskell Composition (.) Against Straight Pipe Operator F # (|>)

In F #, using the pipe-forward operator, |> , is pretty common. However, in Haskell, I only ever saw a functional composition, (.) That is used. I understand that they are connected , but is there a reason for the language that pipe forwarding is not used in Haskell or is it something else?

+92
composition functional-programming haskell f #
Sep 21 '09 at 22:04
source share
10 answers

I'm thinking a little ...

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

Language differences : I don’t know enough about both languages ​​for comparison, but perhaps the rules for generalizing bindings are different enough to affect this. For example, I know in F # sometimes I write

 let f = exp 

will not compile and you need an explicit eta conversion:

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

to do this compile. It also distracts people from the style without glasses / composition and from the style of pipelining. In addition, F # type inference sometimes requires pipelining, so a known type appears on the left (see here ).

(Personally, I find the glasses-free style unreadable, but I believe that every new / unusual thing seems unreadable until you get used to it.)

I think both are potentially viable in any language, and history / culture / accident can determine why each community has settled in its “attractor”.

+60
Sep 21 '09 at 22:26
source share

In F # (|>) it is important because of checking the label from left to right. For example:

 List.map (fun x -> x.Value) xs 

typically, typecheck will not be checked, because even if the type xs is known, the type of the x argument for lambda is unknown at the time that typechecker sees it, so it does not know how to enable x.Value .

Unlike

 xs |> List.map (fun x -> x.Value) 

will work fine, because type xs will result in a known type x .

Type checking is required from left to right due to name resolution contained in constructs of type x.Value . Simon Peyton Jones has written a proposal to add the same name resolution to Haskell, but he suggests using local restrictions to track whether a type supports a particular operation or not. Therefore, in the first example, the requirement that x need the Value property is carried forward until xs is noticed, and this requirement can be resolved. However, this makes the type system difficult.

+82
Sep 22 '09 at 10:12
source share

More speculation, this time from the prevailing side of Haskell ...

($) is a flip (|>) , and its use is quite common when you cannot write free code. Therefore, the main reason that (|>) not used in Haskell is because its place is already taken ($) .

Also, speaking a little from the experience of F #, I think that (|>) so popular in F # code that it looks like a Subject.Verb(Object) OO structure. As F # strives for seamless functional integration / OO, Subject |> Verb Object is a pretty smooth transition for new functional programmers.

Personally, I like to think left-right, so I use (|>) in Haskell, but I don’t think that many other people do it.

+42
Sep 22 '09 at 6:57
source share

I think we're confusing. Haskell ( . ) Is equivalent to F # ( >> ). Not to be confused with F # ( |> ), which is just an inverted function of the application and similar to Haskell ( $ ) - reverseed:

 let (>>) fgx = g (fx) let (|>) xf = fx 

I find Haskell programmers often use $ . Perhaps not as often as F # programmers tend to use |> . On the other hand, some F # guys use >> to an absurd degree: http://blogs.msdn.com/b/ashleyf/archive/2011/04/21/programming-is-pointless.aspx

+30
Apr 22 2018-11-17T00:
source share

If you want to use F # |> in Haskell, then Data.Function is the & operator (since base 4.8.0.0 ).

+19
Sep 27 '15 at 8:31
source share

Composition from left to right in Haskell

Some people use the style from left to right (message) in Haskell. See, for example, the mps Hackage library. Example:

 euler_1 = ( [3,6..999] ++ [5,10..999] ).unique.sum 

I think that in some situations this style looks good, but it is harder to read (you need to know the library and all its operators, overridden (.) Also bothers).

In the composition operator "Control.Category" there are also left and right, as well as composition elements from right to left, part of the base package, Compare >>> and <<< respectively:

 ghci> :m + Control.Category ghci> let f = (+2) ; g = (*3) in map ($1) [f >>> g, f <<< g] [9,5] 

There is a good reason sometimes to prefer a composition from left to right: the evaluation order follows the reading order.

+16
May 26 '10 at
source share

I saw that >>> used for flip (.) , And I often use it myself, especially for long chains that are best understood from left to right.

>>> actually from Control.Arrow and only works on a few functions.

+15
Oct 02 '09 at 0:35
source share

In addition to style and culture, it comes down to optimizing the language design for clean or unclean code.

The |> operator is common in F # mainly because it helps to hide two restrictions that appear with predominantly unclean code:

  • Output from left to right without structural subtypes.
  • Limit value.

Please note that the previous restriction does not exist in OCaml, because subtyping is structural and not nominal, therefore the structural type is easily specified by unification as the type progresses.

Haskell accepts another compromise, preferring to focus on predominantly clean code, where these restrictions can be removed.

+12
Apr 23 2018-11-23T00:
source share

This is my first day to try Haskell (after Rust and F #), and I was able to define the F # | >:

 (|>) :: a -> (a -> b) -> b (|>) xf = fx infixl 0 |> 

and it seems to work:

 factorial x = case x of 1 -> 1 _ -> x * factorial (x-1) main = 5 |> factorial |> print 

I am sure that a Haskell expert can give you an even better solution.

+1
Aug 10 '17 at 20:05
source share

I think the F # pipe ( |> ) operator should be against ( & ) in haskell.

 // pipe operator example in haskell factorial :: (Eq a, Num a) => a -> a factorial x = case x of 1 -> 1 _ -> x * factorial (x-1) 
 // terminal ghic >> 5 & factorial & show 

If you don't like the ( & ) operator, you can configure it as F # or Elixir:

 (|>) :: a -> (a -> b) -> b (|>) xf = fx infixl 1 |> 
 ghci>> 5 |> factorial |> show 

Why infixl 1 |> ? See the document in Data-Function (&)

infixl = infix + left associativity

infixr = infix + right associativity




(.)

( . ) means the composition of the function. This means (fg) (x) = f (g (x)) in mathematics.

 foo = negate . (*3) 
 // ouput -3 ghci>> foo 1 // ouput -15 ghci>> foo 5 

it is equal

 // (1) foo x = negate (x * 3) 

or

 // (2) foo x = negate $ x * 3 

The ( $ ) operator is also defined in Data-Function ($) .

( . ) is used to create a Hight Order Function or closure in js . See an example:

 // (1) use lamda expression to create a Hight Order Function ghci> map (\x -> negate (abs x)) [5,-3,-6,7,-3,2,-19,24] [-5,-3,-6,-7,-3,-2,-19,-24] // (2) use . operator to create a Hight Order Function ghci> map (negate . abs) [5,-3,-6,7,-3,2,-19,24] [-5,-3,-6,-7,-3,-2,-19,-24] 

Wow, Less is (code) is better.




Compare |> and .

 ghci> 5 |> factorial |> show // equals ghci> (show . factorial) 5 // equals ghci> show . factorial $ 5 

Differences between left —> right and right —> left . ⊙﹏⊙ |||

humanization

|> and & better than .

as

 ghci> sum (replicate 5 (max 6.7 8.9)) // equals ghci> 8.9 & max 6.7 & replicate 5 & sum // equals ghci> 8.9 |> max 6.7 |> replicate 5 |> sum // equals ghci> (sum . replicate 5 . max 6.7) 8.9 // equals ghci> sum . replicate 5 . max 6.7 $ 8.9 

How to make functional programming in an object-oriented language?

please visit http://reactivex.io/

IT support:

  • Java: RxJava
  • JavaScript: RxJS
  • C #: Rx.NET
  • C # (Unity): UniRx
  • Scala: RxScala
  • Clojure: RxClojure
  • C ++: RxCpp
  • Lua: RxLua
  • Ruby: Rx.rb
  • Python: RxPY
  • Go: RxGo
  • Groovy: RxGroovy
  • JRuby: RxJRuby
  • Kotlin: RxKotlin
  • Swift: RxSwift
  • PHP: RxPHP
  • Elixir: Reactive
  • Dart: RxDart
0
May 15 '19 at 8:34
source share



All Articles