You're confusing pipe's syntax and infix. Pipe is defined like this:

(|>) x f = f x

And used like this

x |> f == f x

So pipe has an inherent flip because it is used to chain otherwise 
right-building statements.

e.g. 

List.sum (List.filter isOdd [1, 2, 3])

vs

[1, 2, 3]
|> List.filter isOdd
|> List.sum

Pipe is inherently right-building, so operations like subtract or string 
concatenation are not suitable for it since they are only left associative.

List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick 
The "

On Friday, December 9, 2016 at 1:05:56 AM UTC-6, Aaron VonderHaar wrote:
>
> What's confusing here is how currying works with infix operators.  It's 
> idiomatic in Elm to have your accumulator be the last argument, and, for 
> instance, if you were writing your own data type, you would want to write 
> your functions so that they can be chained together easily:
>
>     myMatrix
>         |> scale 2
>         |> subtract 5
>         |> subtractMatrix myOtherMatrix
>         |> normalize
>
>
> But as an infix operator (-) is not able to follow that convention;
>
>     5
>         |> (-) 3
>         |> (-) 1
>
> is confusingly equivalent to `(1 - (3 - 5))` rather than to `5 - 3 - 1`
>
>
> If you had a function `subtract` such that
>
>     5 |> subtract 3 |> subtract 1 == (5 - 3 - 1)
>
> then you could use that function with fold as you intend
>
>     List.foldl subtract 0 [1, 2, 3, 4]  ==  -10
>
> You can achieve the same result with
>
>     List.foldl (flip (-)) 0 [1, 2, 3, 4]  ==  -10
>
>
> Another way to put it is, in Elm, folds expand in the following way:
>
>     List.foldl f x [b, c, d]  ==  x |> f b |> f c |> f d 
>     List.foldr f x [b, c, d]  ==  f b <| f c <| f d <| x
>
>
> On Thu, Dec 8, 2016 at 7:50 PM, Kasey Speakman <[email protected] 
> <javascript:>> wrote:
>
>> (deleted and corrected original post with proper expansion of Elm's foldl)
>>
>> I know this is a really old thread, but I ran into this precise question 
>> and thought I would add a perspective.
>>
>> The form a -> b -> b is not left-building, regardless of the direction 
>> you are traversing the list.
>>
>> An example: Starting from zero, subtract the numbers 1, 2, and 3. The 
>> expected answer is -6.
>>
>> List.foldl (-) 0 [1, 2, 3]
>> -> returns -6 in Haskell (well, actually tested in F# which uses same 
>> order as Haskell)
>>     expands to: ((0 - 1) - 2) - 3 = -6
>> -> returns 2 in Elm
>>     expands to: 3 - ((1 - 0) - 2)
>>
>> Elm's expansion is wonky for this. It appears to be center-building:
>>     List.foldl (-) 0 [1] -- returns 1, expands 1 - 0
>>     List.foldl (-) 0 [1, 2] -- returns -1, expands (1 - 0) - 2
>>     List.foldl (-) 0 [1, 2, 3] -- returns 2, expands 3 - ((1 - 0) - 2)
>>     List.foldl (-) 0 [1, 2, 3, 4] -- returns -2, expands (3 - ((1 - 0) - 
>> 2)) - 4
>>
>> When a and b are the same type it will only return the correct answer if 
>> the fold operation is also commutative or if flip is used to correct the 
>> ordering. When a and b are not the same type, the compiler will provide an 
>> error for wrong ordering of course.
>>
>> I started out on the side that a -> b -> b was correct as that feels like 
>> proper "reduction" or chainable syntax. But after exploring it, it is 
>> clearly not left-building. Makes sense when you consider this form is used 
>> with pipe to convert right-building operations into left-reading code. e.g. 
>> a 
>> |> f |> g |> h instead of h (g (f a))
>>
>> On Tuesday, July 16, 2013 at 6:13:01 AM UTC-5, Evan wrote:
>>>
>>> Gotcha, I definitely see the reasoning :)
>>>
>>>
>>> On Tue, Jul 16, 2013 at 12:54 PM, Balazs Komuves <[email protected]> 
>>> wrote:
>>>
>>>>
>>>> I was not engaging in debate, religious or not (though I tend to have 
>>>> very strong opinions about these questions). I was explaining why I think 
>>>> Haskell uses the order it uses (because it is distinguished from a 
>>>> mathematical viewpoint). Of course you are not required to follow that 
>>>> convention, I was just pointing out that it is not simply an ad-hoc choice.
>>>>
>>>> Balazs
>>>>
>>>>
>>>>
>>>> On Tue, Jul 16, 2013 at 12:21 PM, Evan Czaplicki <[email protected]> 
>>>> wrote:
>>>>
>>>>> I think this might be a religious debate on some level. My first 
>>>>> functional languages were Scheme 
>>>>> <http://docs.racket-lang.org/reference/pairs.html#(def._((lib._racket/private/list..rkt)._foldl))>
>>>>>  
>>>>> and Standard ML <http://www.standardml.org/Basis/list.html>. The 
>>>>> libraries I just linked both use the same argument order for foldl and 
>>>>> foldr as in Elm. I was raised a certain way and it just stuck in my mind. 
>>>>> I 
>>>>> suspect that everyone prefers the order they learned first because it 
>>>>> matches their mental model.
>>>>>
>>>>> I wrote up a bunch of "reasoning", but really, I am just engaging in 
>>>>> the religious debate. I'd feel bad deleting it all though, so here is 
>>>>> some 
>>>>> of it:
>>>>>
>>>>> OCaml's list library 
>>>>> <http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html> does it 
>>>>> the way you suggest. I find this order offensive on some level.
>>>>>
>>>>> The big questions for "physical" argument order are as follows:
>>>>>
>>>>>    - What is the type of `fold` or `reduce`? When you fold an 
>>>>>    unordered thing, is it from the right or the left? 
>>>>>    - What is the type of `foldp`? Which way does time go? Is this 
>>>>>    cultural?
>>>>>
>>>>> I don't find these questions particularly useful, and I don't think 
>>>>> programmers should have to wonder about them to use fold and foldp.
>>>>>
>>>>> At the end of the day, I chose the types on purpose. I find them 
>>>>> easier to use, easier to teach, easier to understand. I want to keep them 
>>>>> this way.
>>>>>
>>>>>
>>>>> On Tue, Jul 16, 2013 at 10:40 AM, Balazs Komuves <[email protected]> 
>>>>> wrote:
>>>>>
>>>>>>
>>>>>> The Haskell version of the foldl is the "right one" in the following 
>>>>>> sense:
>>>>>>
>>>>>> foldl makes sense in general for left-associative operators, and 
>>>>>> foldr makes sense for right-associative operators.
>>>>>> Left-associative operators must have the type (a -> b -> a), while 
>>>>>> right-associative operators must have type (a -> b -> b).
>>>>>>
>>>>>> I think the fact that you cannot change a foldr to foldl without 
>>>>>> changing the types is actually an advantage: it forces you to think 
>>>>>> about 
>>>>>> which version is the "proper" one, and you cannot accidentally do the 
>>>>>> wrong 
>>>>>> one. Of course sometimes it can be inconvenient.
>>>>>>
>>>>>> What I somewhat dislike in the Haskell version of foldr (not foldl), 
>>>>>> is that while 
>>>>>>
>>>>>> (foldl . foldl . foldl) etc makes sense, (foldr . foldr) does not; 
>>>>>> for that to work you would have to flip the last two arguments:
>>>>>>
>>>>>> myfoldr :: (a -> b -> b) -> ([a] -> b -> b)
>>>>>> myfoldr f xs y = foldr f y xs
>>>>>>
>>>>>> But the practicality of this change is debatable, I guess.
>>>>>>
>>>>>> Balazs
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Wed, Jul 10, 2013 at 4:38 PM, Evan Czaplicki <[email protected]> 
>>>>>> wrote:
>>>>>>
>>>>>>> It's partly about composability (i.e. the data structure should be 
>>>>>>> last).
>>>>>>>
>>>>>>> It is also about reuse. In Elm it is valid to say:
>>>>>>>
>>>>>>> foldl (::) []
>>>>>>> foldr (::) []
>>>>>>>
>>>>>>> If I want to change the order of my traversal, I should not *also* need 
>>>>>>> to change the definition of mildly related functions or start using 
>>>>>>> flip on things.
>>>>>>>
>>>>>>> Finally, once you know that the accumulator is always the second 
>>>>>>> argument, you do not have to look at docs anymore. Even now I forget 
>>>>>>> the 
>>>>>>> order of arguments in Haskell's folds and need to look it up.
>>>>>>>
>>>>>>> I first learned this way from Standard ML 
>>>>>>> <http://www.standardml.org/Basis/list.html>, and it is my favorite 
>>>>>>> by far.
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Jul 10, 2013 at 4:12 PM, Tim hobbs <[email protected]> 
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Well, elm's ordering is more useful.  For example, I recently had a 
>>>>>>>> case where I wrote:
>>>>>>>>
>>>>>>>> let
>>>>>>>>   irrelivantFuncitonName fold = fold blabla default list
>>>>>>>> in
>>>>>>>>  irrelivantFunctionName foldl + irrelivantFuncitonName foldr
>>>>>>>>
>>>>>>>> In Haskell, the same example ends up being
>>>>>>>>
>>>>>>>> let
>>>>>>>>   irrelivantFuncitonName fold = fold blabla default list
>>>>>>>> in
>>>>>>>>  irrelivantFunctionName foldl + irrelivantFuncitonName (\f d l-> 
>>>>>>>> foldr (\a b->f b a) d l)
>>>>>>>>
>>>>>>>> Tim
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wednesday, July 10, 2013 4:03:23 PM UTC+2, Zsombor Nagy wrote:
>>>>>>>>>
>>>>>>>>> Hi! 
>>>>>>>>>
>>>>>>>>> I wonder why is the foldl in Elm and in Haskell calling the binary 
>>>>>>>>> operator with arguments in a different order? 
>>>>>>>>>
>>>>>>>>> foldl (\t acc -> acc + 1) 0 [1, 1, 1, 1, 1, 1] 
>>>>>>>>> haskell: 2 
>>>>>>>>> Elm: 6 
>>>>>>>>>
>>>>>>>>> For me the haskell way seems more straightforward, but maybe that 
>>>>>>>>> "optimal composibility guideline" makes this turn around? 
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> zs
>>>>>>>>
>>>>>>>> -- 
>>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>>> Groups "Elm Discuss" group.
>>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>>> send an email to [email protected].
>>>>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>>>>>  
>>>>>>>>  
>>>>>>>>
>>>>>>>
>>>>>>> -- 
>>>>>>> You received this message because you are subscribed to the Google 
>>>>>>> Groups "Elm Discuss" group.
>>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>>> send an email to [email protected].
>>>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>>>>  
>>>>>>>  
>>>>>>>
>>>>>>
>>>>>> -- 
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "Elm Discuss" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, 
>>>>>> send an email to [email protected].
>>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>>>  
>>>>>>  
>>>>>>
>>>>>
>>>>> -- 
>>>>> You received this message because you are subscribed to the Google 
>>>>> Groups "Elm Discuss" group.
>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>> an email to [email protected].
>>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>>  
>>>>>  
>>>>>
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Elm Discuss" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to [email protected].
>>>> For more options, visit https://groups.google.com/groups/opt_out.
>>>>  
>>>>  
>>>>
>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "Elm Discuss" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to