Head vs Tail - Array vs value

Im new to Haskell. I can understand why TAIL returns an array. But HEAD …it seems to return a value instead of a single element array. Am I wrong? Why is this?

Yes, it returns the first element of the list.

But what confuses me is that it is not shown as [x], but rather, x

head does not return a list. It returns a ‘value’, as you said. The function gives you back whatever the first element of the list is, just as it is, not inside of a new list. If you want it to be inside of a list you can use the result of head and give it to another function that puts something inside of a list. The reason it is not shown as [x] is because it is not a list, it’s just the first element itself. This is reflected in the type of head:

head :: [a] -> a

This says that head takes a list of a’s and returns an a. If head was going to return [x], which would be a list containing only the first object x, it would have the type signature

differentHead :: [a] -> [a]

If you really want an explanation for why head returns the first element of a list itself instead of a list containing that element, it has to do with the idea of structural recursion, and specifically how lists are defined. head and tail are just car and cdr from Lisp.

Internally, lists are constructed just as either the empty list or an element (the head) in addition to another list (the tail). The head and tail functions return the values used to construct the list.

If you want a function that gives you the start of the list as a list, you can use take. It returns the first n elements of a list. So take 1 gets the first element of the list, in a 1-element list. take 2 [1, 2, 3] is [1, 2].

Also, using head is dangerous because the list might be empty. In most code, the list will be pattern-matched on. You can use listToMaybe to get a Maybe x. If you don’t yet know what Maybe is, please disregard this.

That is very helpful. Thank you!

1 Like

Good to know. I’ll make a note of this for later!

You can get the version you want as follows: take 1 [1,2,3] will give [1]. This is a safe function, in the sense that take 1 [] returns [], while head [] returns a runtime error, which is why its use is discouraged.

1 Like