Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is this function equivalent to getting the last item in a list?

Tags:

haskell

After completing the first problem ("Find the last element of a list") in the 99 questions exercises, I wanted to see how my solution compared with others and I found this solution.

myLast' = foldr1 (const id)

This documentation seems to show that foldr1 takes two arguments, the first being a function and the second being a list. But this definition only appears to take a function as an argument. Is there an implicit definition of the arguments passed like this?

myLast' xs = foldr1 (const id) xs

I have looked up the definitions of foldr1, const, and id, but I'm having a hard time understanding how those three work together to return the last item in the list.

like image 633
Cory Klein Avatar asked Sep 03 '13 17:09

Cory Klein


People also ask

How do you find the last item in a list?

Get the last item of a list using list. To get the last element of the list using list. pop(), the list. pop() method is used to access the last element of the list.

How do you get the final value of a list in Python?

To get the last element of the list in Python, use the list[-1] syntax. The list[-n] syntax gets the nth-to-last element. So list[-1] gets the last element, and list[-2] gets the second to last. The list[-1] is the most preferable, shortest, and Pythonic way to get the last element.

How do you get the last value in a list or tuple?

Hence, in order to access last element from tuple we use index value of -1. len() calculates the total length of tuple. Using this value we can the index of last element. Since indexing in python starts with 0, index of last element will be (length of tuple)-1.

What is the function that adds a value to the end of a list?

One of those methods is .append() , you can add items to the end of an existing list object. You can also use . append() in a for loop to populate lists programmatically.


2 Answers

You're exactly right. In Haskell, a function that takes two arguments can actually be treated as a function that takes one argument and returns another function that takes an argument; this is known as currying. Note that the function signature for foldr1 is:

(a -> a -> a) -> [a] -> a

While we often think of it as "a function that takes a function and a list as arguments and returns a value", it's really "a function that takes a function as an argument and returns a function that takes a list and returns a value".

like image 187
mipadi Avatar answered Sep 21 '22 15:09

mipadi


As mipadi explains, the function is being curried. That explains how the list argument gets there, but perhaps doesn't explain how the actual fold works.

The const id bit is a little trixy. foldr1 is expecting to get something that has the type a -> a -> a. The definitions of these functions are

const :: x -> y -> x
const x y = x

id :: x -> x
id x = x

So, mangling that all together, we have

const id =
\ y -> id =
\ y -> \ x -> x =
\ y x -> x

In order words, const id does the same thing as flip const; it's a 2-argument function that throws the first argument away, and returns the second one. It's not terribly obvious that this is so; IMHO, flip const would be clearer.

foldr1 will call this function with the old value as the first argument, and the next list element as the second argument. This function always returns the next list element. The final output from foldr is the last output from the function, which will be the last element of the entire list.

like image 22
MathematicalOrchid Avatar answered Sep 21 '22 15:09

MathematicalOrchid