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.
