在 Haskell 使用 Maybe [String]
Using Maybe [String] at Haskell
我想 return 使用 Maybe [String] 的字符串,但我无法使用 Maybe 做到这一点。
我应该定义一个实例吗?
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)
这是同一个函数 verEmails,我在这里使用 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)
GHCi 给我的错误:
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))'
问题来自尝试执行 e : verEmails n xs
,因为 verEmails n xs
不是 return 列表,而是包含在 Maybe
中的列表。处理此问题的最简单方法是使用 Data.Maybe.fromMaybe
函数:
fromMaybe :: a -> Maybe a -> a
fromMaybe onNothing Nothing = onNothing
fromMaybe onNothing (Just a) = a
这里我假设您想要 return Just aList
其中 aList
包含从传入的 Agenda
过滤的所有电子邮件。这意味着唯一verEmails
将 return Nothing
的方式是当传入的议程为空时。所以我们有
verEmails n [] = Nothing
verEmails n ((nome, ((Email e):ls)):xs)
= if n == nome
then Just $ e : (fromMaybe [] $ verEmails n xs)
else verEmails n xs
这只是简单地将 verEmails n xs
从 Maybe [String]
转换为 [String]
,默认为空列表,添加 e
,然后将其包装回 [=25] =].
附带说明一下,您的函数并未涵盖所有可能的情况,如果我 运行 verEmails n ((nome, []):xs)
会怎样?甚至 verEmails n ((nome, [Casa 1]):xs)
?
我想 return 使用 Maybe [String] 的字符串,但我无法使用 Maybe 做到这一点。
我应该定义一个实例吗?
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)
这是同一个函数 verEmails,我在这里使用 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)
GHCi 给我的错误:
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))'
问题来自尝试执行 e : verEmails n xs
,因为 verEmails n xs
不是 return 列表,而是包含在 Maybe
中的列表。处理此问题的最简单方法是使用 Data.Maybe.fromMaybe
函数:
fromMaybe :: a -> Maybe a -> a
fromMaybe onNothing Nothing = onNothing
fromMaybe onNothing (Just a) = a
这里我假设您想要 return Just aList
其中 aList
包含从传入的 Agenda
过滤的所有电子邮件。这意味着唯一verEmails
将 return Nothing
的方式是当传入的议程为空时。所以我们有
verEmails n [] = Nothing
verEmails n ((nome, ((Email e):ls)):xs)
= if n == nome
then Just $ e : (fromMaybe [] $ verEmails n xs)
else verEmails n xs
这只是简单地将 verEmails n xs
从 Maybe [String]
转换为 [String]
,默认为空列表,添加 e
,然后将其包装回 [=25] =].
附带说明一下,您的函数并未涵盖所有可能的情况,如果我 运行 verEmails n ((nome, []):xs)
会怎样?甚至 verEmails n ((nome, [Casa 1]):xs)
?