views:

743

answers:

2

A bit of a neophyte haskell question, but I came across this example in Haskell's tutorial examples. For "find the last element of a list" there are some obvious versions, like

last' [x] = x
last' (_:xs) = last' xs

But I can't make sense of an alternate version presented:

myLast' = foldr1 (const id)

So, in trying to make sense of what the application of the id function is doing, I tried in ghci:

const id 1 2 -> gives 2

This binds like this:

(const id) 1 2 -> gives 2

And not like this:

 const (id 1) 2 -> gives 1

But I'm not making sense of this. (const id) should translate to something like

`(\x y->x) (\x->x)`

Shouldn't this return a function that simply returns the id of its first element? Or, how is the function order making (const id) behave differently than const?

+18  A: 

The definition of const is

const x = \_ -> x

Hence, (const id) is a function which takes one argument and always returns id and

const id 1 2 = (\_ -> id) 1 2
             = id 2
             = 2

The definition of foldr1 is

foldr1 f [x] = x
foldr1 f (x:xs) = f x (foldr1 f xs)

If we have

myLast' = foldr1 (const id)

then

myLast' [x] = foldr1 (const id) [x]
              {- definition of foldr1 -}
            = x

and

myLast' (x:xs) = foldr1 (const id) (x:xs)
                 {- definition of foldr1 -}
               = (const id) x (foldr1 (const id) xs)
                 {- definition of const -}  
               = (\_ -> id) x (foldr1 (const id) xs)
                 {- function application -}  
               = id (foldr1 (const id) xs)
                 {- definition of id -}  
               = foldr1 (const id) xs
                 {- definition of myLast' -}  
               = myLast' xs

which agrees with the definition of last'.

Chris Conway
ahhh. Didn't make the connection of the const returning the function. Thanks for the explanation.
Steve B.
This is a great explanation, and stepping through it I can see how it works. But is foldr1 (const id) really the idiomatic way to do a myLast function? The first example given seems way more clear...
J Cooper
I wouldn't say it's idiomatic... Haskell geeks enjoy working out how to express things in a "point-free" style, or purely in terms of folds. It becomes a kind of programming puzzle. The first version is much more clear.
Chris Conway
+6  A: 

I rely heavily on :t when trying to understand Haskell. In this case:

Prelude> :t const id
const id :: b -> a -> a

might have helped you see what was going on.

Magnus
To clarify, ":t" is a command you can use in GHCI to print the type of an expression.
Jay Conrod