我想使用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)
Run Code Online (Sandbox Code Playgroud)
这是相同的函数 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)
Run Code Online (Sandbox Code Playgroud)
GHCi 给我的错误:
Run Code Online (Sandbox Code Playgroud)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不返回列表,而是包含在Maybe. 处理此问题的最简单方法是使用该Data.Maybe.fromMaybe函数:
fromMaybe :: a -> Maybe a -> a
fromMaybe onNothing Nothing = onNothing
fromMaybe onNothing (Just a) = a
Run Code Online (Sandbox Code Playgroud)
在这里,我假设你希望回到Just aList这里aList包含了从过滤过的所有电子邮件Agenda中传递,这意味着,只有这样,verEmails将返回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
Run Code Online (Sandbox Code Playgroud)
这只是简单地verEmails n xs从Maybe [String]to转换[String],默认为空列表,在 prepends e,然后将其包装在 a 中Just。
作为旁注,您的功能并未涵盖所有可能的情况,如果我要运行会发生什么verEmails n ((nome, []):xs)?甚至verEmails n ((nome, [Casa 1]):xs)?
| 归档时间: |
|
| 查看次数: |
2371 次 |
| 最近记录: |