在 Haskell 中使用 Maybe [String]

问题描述 投票:0回答:1

我想使用 Maybe [String] 返回一个

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))'
haskell
1个回答
6
投票

问题来自于尝试执行

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

这里我假设您想要返回

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

这只是简单地将

verEmails n xs
Maybe [String]
转换为
[String]
,默认为空列表,在前面添加
e
,然后将其包装回
Just
中。

顺便说一句,你的函数并没有涵盖所有可能的情况,如果我运行

verEmails n ((nome, []):xs)
会发生什么? 或者甚至
verEmails n ((nome, [Casa 1]):xs)

© www.soinside.com 2019 - 2024. All rights reserved.