I want to return a string using Maybe [String]
, but I can't manage to do it using Maybe
.
Should I define an instance?
data Contacto = Casa Integer
| Trab Integer
| Tlm Integer
| Email String
deriving (Show)
type Nome = String
type Agenda = [(Nome, [Contacto])]
addEmail :: Nome -> String -> Agenda -> Agenda
addEmail n email agenda = (n, [Email email]):(agenda)
verEmails :: Nome -> Agenda -> [String]
verEmails n [] = []
verEmails n ((nome, ((Email e):ls)):xs) = if n == nome then (e:(verEmails n xs))
else (verEmails n xs)
Here is the same function verEmails
, where I use Maybe
:
verEmails :: Nome -> Agenda -> Maybe [String]
verEmails n [] = Nothing
verEmails n ((nome, ((Email e):ls)):xs) = if n == nome then Just (e:(verEmails n xs))
else (verEmails n xs)
The error that GHCi gives me:
Couldn't match expected type `[String]' with actual type `Maybe [String]' In the return type of a call of `verEmails' In the second argument of `(:)', namely `(verEmails n xs)' In the first argument of `Just', namely `(e : (verEmails n xs))'
The problem comes from trying to do e : verEmails n xs
, since verEmails n xs
does not return a list, but a list enclosed in Maybe
. The easiest way to handle this is to use the Data.Maybe.fromMaybe
function:
fromMaybe :: a -> Maybe a -> a
fromMaybe onNothing Nothing = onNothing
fromMaybe onNothing (Just a) = a
Here I'm presuming you would want to return Just aList
where aList
contains all the emails filtered from the Agenda
passed in. This means that the only way verEmails
will return Nothing
is when the agenda passed in is empty. So we have
verEmails n [] = Nothing
verEmails n ((nome, ((Email e):ls)):xs)
= if n == nome
then Just $ e : (fromMaybe [] $ verEmails n xs)
else verEmails n xs
This just simply converts verEmails n xs
from Maybe [String]
to [String]
, defaulting to the empty list, prepends e
, then wraps it back up in a Just
.
As a side note, your function does not cover all possible cases, what happens if I were to run verEmails n ((nome, []):xs)
? Or even verEmails n ((nome, [Casa 1]):xs)
?