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 actually makes the fold right-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 - (2 - (1 - 0)) = 2 -- right-building
Elm's foldl implementation is actually equivalent to a right fold of a
reversed list. So 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]
> <javascript:>> 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]
>> <javascript:>> 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]
>>> <javascript:>> 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]
>>>> <javascript:>> 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]
>>>>> <javascript:>> 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] <javascript:>.
>>>>>> 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/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/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/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/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/d/optout.