Reputation: 57333
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?
Upvotes: 21
Views: 2458
Reputation: 56019
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'
.
Upvotes: 31
Reputation: 4714
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.
Upvotes: 9