Friday, March 4, 2011

Haskell Function Application

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?

From stackoverflow
  • 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'.

    Steve B. : ahhh. Didn't make the connection of the const returning the function. Thanks for the explanation.
    J Cooper : 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...
    Chris Conway : 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.
  • 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.

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

0 comments:

Post a Comment