Haskell-如果key在关联列表中,则返回True

时间:2015-01-30 05:03:26

标签: haskell

我正在尝试创建一个接受String作为参数的函数,如果String作为以下关联列表中的键值存在,则返回布尔值True

lis = [("Kingston", [12.2, 17.3, 9.1]), ("Ottawa", [10.0, 13.9, 8.2])]

这是我的功能,如果可能的话,我希望能够使用列表理解来做到这一点:

check :: String -> [(String,a)] -> Bool
check val alist
    | [ key | (key,num)<-alist, key==val] = True
    | otherwise = False

如果有帮助,我得到的错误是:

Couldn't match expected type ‘Bool’ with actual type ‘[String]’

有人能告诉我我的错误是什么吗?

3 个答案:

答案 0 :(得分:3)

您正在使用[String]类型的列表理解,其中需要Bool

您需要做的是检查列表理解是否为空。例如,使用null

check :: String -> [(String,a)] -> Bool
check val alist = not $ null [ key | (key,num) <- alist, key==val ]

答案 1 :(得分:2)

保护条款中的表达式必须评估为Bool。这不是Python,它不会自动发生。尝试

check val alist
    | not $ null [key | (key, num) <- alist, key == val] = True
    | otherwise = False

但这可以简单地写成简单的

check val alist = not $ null [key | (key, num) <- alist, key == val]

因为警卫只是检查值是True还是False

答案 2 :(得分:1)

在haskell中,守卫应该评估为布尔值。所以,这样的事情会起作用:

check :: String -> [(String,a)] -> Bool
check val alist
    | length [ key | (key,num) <-alist, key==val] >= 1 = True
    | otherwise = False

但请注意,这必须遍历整个列表。

在以下代码中,它不必遍历整个列表并且效率更高:

check :: String -> [(String,a)] -> Bool
check val alist
    | efficientCheck [ key | (key,num) <-alist, key==val] = True
    | otherwise = False

efficientCheck :: [a] -> Bool
efficientCheck (x:xs) = True
efficientCheck _ = False

演示:

λ> check "bye" [("hi",3)]
False
λ> check "hi" [("hi",3),("bye",4)]
True