Help implementing List.head : how to throw an exception

Hi,

I am learning Haskell and I come from an imperative programming language background.

I am trying to re implement some functions in the Data.List ghc library like head :

head :: [a] -> a

But when ran with an empty list it should throw an exception :

Prelude> head []
*** Exception: Prelude.head: empty list

This is fairly simple but I have this :

head :: [a] -> a
head [] = ??
head (x:xs) = x

How can I implement something similar in Haskell? I tried to look at the source code but it uses rather complicated structures and use a raise# function that I can’t find in the documentation.

Thanks! :wink:

Hello Joseph,
you definitely can. The simplest way is to use error:

> :t error
error :: String -> a

and if you want to get more fancy, take a look at throw and friends in in Control.Exception.

1 Like

Thanks for the answer, this is what I wanted!

I have another question, if I want to print the result of the head function like this :

module List where

head :: [a] -> a
head [] = error "List is empty"
head (x:xs) = x
module Main where

import List

main :: IO ()
main = print (List.head [])

It gives me this :

Main.hs:7:8: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘print’
      prevents the constraint ‘(Show a0)’ from being solved.

How can I solve that?

By the way the error function takes a String parameter and return a value of type a but what is this value, it means it can be any type?

The ambiguous type variable error is due to the fact that you are applying head to an emty list. This could be an empty list of any type. [] :: [Int] is an empty list of Int while []::[Char] is an empty list of Chars.

For the second question, error produces an exception and “returns” bottom, which is a special value that inhabits every type. I would suggest to read the first few paragraphs of this article.

3 Likes