expection to this exceptation.

On Fri, Dec 9, 2016 at 2:17 PM, Nick H <[email protected]> wrote:

> I would disagree with "not expected in general." In general -- when a and
> b are different types -- Elm's API design guidelines should set you up to
> always expect a -> b -> b and never b -> a -> b. If the definition of foldl
> were changed to take the latter, it would be the only exception to this
> expectation.
>
> On Fri, Dec 9, 2016 at 7:03 AM, Kasey Speakman <[email protected]>
> wrote:
>
>> Ok, correction
>>
>> List.foldl (-) 0 [1, 2, 3]
>> -- returns 2
>> -- expands to 3 - (2 - (1 - 0)) = 2
>>
>> During my testing last night, I had a typo (foldr instead of foldl) when
>> I was testing the expansions. That was the center-building behavior.
>>
>> Using the form a -> b -> b is right-building regardless of the order the
>> list is traversed. Traversing from head to tail is equivalent to reversing
>> the list and building right. This is obviously broken for left-associative
>> only operations and not expected in general.
>>
>> On Friday, December 9, 2016 at 8:44:25 AM UTC-6, Kasey Speakman wrote:
>>>
>>> Sorry, that last bit was an example of what happens in Elm when folding
>>> with string concat (++). That's unexpected behavior from a left fold.
>>>
>>> List.foldl (++) "" ["The ", "quick ", "brown "]  -- returns "brown quick
>>> The "
>>>
>>> On Friday, December 9, 2016 at 8:26:17 AM UTC-6, Kasey Speakman wrote:
>>>>
>>>> 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]>
>>>>> 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/grou
>>>>>>>>>>>> ps/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].
>>>>>> 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.
>>
>
>

-- 
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