说我有这种格式的元素列表 (U“NAME”,I“Item Name”,INT_HERE) 我想创建一个函数,它接受一个U,一个I并检查它们是否存在于任何元素的列表中,如果是,则返回true,否则返回true。 例如
exists (U "John") (I "Sofa")
[(U "Mark" , I "Legion Y520", 5),
(U "Ahmed" ,I "GTX 1060", 3),
(U "Carole" , I "BMW C-Class", 5),
(U "John" , I "Maximized outlet", 4),
(U "Malik" , I "Honda Civic", 1)]
应该返回错误
这是我尝试过的代码(extractitem和extractuser都正确地提取了项目的第一部分和第二部分,我已经测试了它们,问题应该是这个部分)
exists :: (Eq a, Eq b) => a -> b -> [(a,b,c)] -> Bool
exists y z [] = False
exists y z (x:xs) = if ((extractuser x) == y) then if ((extractitem x) ==
z) then True else False else exists y z xs
这是我得到的错误
Inferred type is not general enough
*** Expression : exists
*** Expected type : (Eq a, Eq b) => a -> b -> [(a,b,c)] -> Bool
*** Inferred type : (Eq a, Eq a) => a -> a -> [(a,a,b)] -> Bool
我还想使第二个函数get具有相同的功能,区别在于它实际显示条件适用的元素/如果它不存在则发出错误消息。
答案 0 :(得分:7)
您应该可以完全使用模式匹配来完成此操作。您当前的错误出现是一个错字,但模式匹配更简单,可以消除部分错误。
exists :: (Eq a, Eq b) => a -> b -> [(a, b, c)] -> Bool
exists u i ((u', i', _):xs) = u == u' && i == i' || exists u i xs
exists _ _ [] = False
或不太明确的递归:
exists :: (Eq a, Eq b) => a -> b -> [(a, b, c)] -> Bool
exists u i = any (\(u', i', _) -> u==u' && i==i')
错误消息
Inferred type is not general enough
*** Expression : exists
*** Expected type : (Eq a, Eq b) => a -> b -> [(a,b,c)] -> Bool
*** Inferred type : (Eq a, Eq a) => a -> a -> [(a,a,b)] -> Bool
似乎表明您的extractitem
功能正在执行:
extractitem (x, _, _) = x
什么时候应该
extractitem (_, y, _) = y