Search code examples
haskellhead

In Haskell, how do you use 'head' without creating a separate function?


I'm very new to using Haskell and I'm unsure about how 'head' works. From my understanding it returns the first element in a list. I've been trying to use it, but I keep getting errors. I added a workaround by creating a separate function that finds the head, however that seems like it should be unnecessary.

I don't understand why calling findHead here:

single x = length (snd(x)) == 1

toList board
    | board == [] = []
    | otherwise = filter single board

findHead board = head (toList board)

is not equivalent to calling toList here:

single x = length (snd(x)) == 1

toList board
    | board == [] = []
    | otherwise =  head (filter single board)

It seems to me that the two should be the same, but only the first one runs. Why aren't they interpreted to be the same? Could you explain this to me? In the code above, 'board' is meant to be a list of tuples which are each the form (x, [a,b,...]).

I've used 'head' in a few simpler things like:

union xs ys 
  | xs == [] = ys
  | ys == [] = xs
  | otherwise = union (tail xs)  (add (head xs) ys)

which seems to work as I would expect it would.


Solution

  • head is partial. In particular, head [] doesn't return normally (throws an exception). This can be difficult to handle in Haskell which is why people often suggest that you avoid partial functions.

    So how do we do that? We have to reflect failure in the type.

    safeHead :: [a] -> Maybe a
    safeHead []     = Nothing
    safeHead (a:as) = Just a
    

    A similar function can be made for tail

    safeTail :: [a] -> Maybe [a]
    safeTail []     = Nothing
    safeTail (a:as) = Just as