我想创建一个函数来接收对的列表(例如[(3,'a'),(7,'d'),(1,'c')]
)和一个键(例如3
)并返回该键的值(在此示例中为'a'
} )。
如果密钥存在,我编写的函数工作正常,但如果我找不到匹配的密钥时尝试返回null
,我会收到错误。
功能是:
lookup1 k lst = lookupH1 k lst
where
lookupH1 k lst
| ((length lst) == 0) = null -- this is the problematic line
| ((fst (head lst)) == k )= snd (head lst)
| otherwise = lookupH1 k (tail (lst))
我该怎么做才能解决这个问题?
答案 0 :(得分:8)
通常最好首先删除你的类型,然后让编译器指导你。
在这种情况下,您现在看到的签名看起来像是:
lookup1 :: Int -> [(Int,Char)] -> Char
但是,Haskell没有可以将Char替换为返回类型的null。因此,通常的做法是使用Maybe代替。那么新的签名就是。
lookup1 :: Int -> [(Int,Char)] -> Maybe Char
这意味着一旦找到值v,你会得到“Just v”,如果你没有,它会产生“Nothing”。
我希望我不会放弃太多,但这是一个使用模式匹配的功能稍微简单的版本。
lookup1 :: Int -> [(Int,Char)] -> Maybe Char
lookup1 k lst = lookupH1 lst
where
lookupH1 [] = Nothing
lookupH1 ((k',v):lst')
| k == k' = Just v
| otherwise = lookupH1 lst'
答案 1 :(得分:2)
null
是一个获取列表并告诉您列表是否为空的函数。由于您的结果不应该是函数,因此使用null
作为结果是类型错误。
在Haskell中没有空指针或空引用这样的东西。如果函数具有结果类型Char
并且函数成功终止(即它不会永远循环或抛出异常),则调用该函数的结果将始终为Char
值,并且没有神奇的null
实体,它在某种程度上是每种类型的价值。
所以你有两个选择:要么在找不到密钥时抛出异常,要么(这是更好的选择)你将函数的结果类型改为Maybe v
而不是v
Haskell中的Maybe t
类型有两个可能的值:Just x
其中x
的类型为t
或Nothing
。因此,对于您的(Int,Char)列表,查找函数可以在找到给定键的值时返回Just v
,或者在Nothing
没有时返回{{1}},然后函数的用户可以进行模式匹配在结果上找出是否找到了一个值,并在找到它时获得该值。
答案 2 :(得分:2)
查看Prelude lookup
函数:它返回类型Maybe b
。具体而言,如果Just x
是与关键字相关联的值,则返回x
,如果找不到关键字,则返回Nothing
。