假设我有这种格式的元素列表(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)]
Run Code Online (Sandbox Code Playgroud)
应该返回False
这是我尝试使用的代码(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
Run Code Online (Sandbox Code Playgroud)
这是我得到的错误
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
Run Code Online (Sandbox Code Playgroud)
我还想使第二个函数get具有相同的功能,区别在于它实际显示条件适用的元素/如果它不存在则发出错误消息.
您应该能够完全使用模式匹配来完成此操作.您当前的错误似乎是一个错字,但模式匹配更直接,并用于消除其中一些错误.
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
Run Code Online (Sandbox Code Playgroud)
或者使用不太明确的递归:
exists :: (Eq a, Eq b) => a -> b -> [(a, b, c)] -> Bool
exists u i = any (\(u', i', _) -> u==u' && i==i')
Run Code Online (Sandbox Code Playgroud)
错误消息
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
Run Code Online (Sandbox Code Playgroud)
似乎表明你的extractitem功能正在做:
extractitem (x, _, _) = x
Run Code Online (Sandbox Code Playgroud)
什么时候应该
extractitem (_, y, _) = y
Run Code Online (Sandbox Code Playgroud)