One way is to lay out the cases exhaustively:
charFromEscape :: Char -> Char
charFromEscape 'n' = '\n'
charFromEscape 't' = '\t'
--- ... --- Help!
You could also use lookup
:
-- this import goes at the top of your source file
import Data.Maybe (fromJust)
charFromEscape :: Char -> Char
charFromEscape c = fromJust $ lookup c escapes
where escapes = [('n', '\n'), ('t', '\t')] -- and so on
The fromJust
bit may look strange. The type of lookup
is
lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
which means for a value of some type over which equality is defined and a lookup table, it wants to give you the corresponding value from the lookup table—but your key isn't guaranteed to be present in the table! That's the purpose of Maybe
, whose definition is
data Maybe a = Just a | Nothing
With fromJust
, it assumes you got Just something
(i.e., c
has an entry in escapes
), but this will fall apart when that assumption is invalid:
ghci> charFromEscape 'r'
*** Exception: Maybe.fromJust: Nothing
These examples will move you along in the exercise, but it's clear that you'd like better error handling. Also, if you expect the lookup table to be large, you may want to look at Data.Map.