我正在尝试创建一个接受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]’
有人能告诉我我的错误是什么吗?
答案 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