import Data.Char
type Games = (String, String, Int)
test :: [Games]
test =
[
("Minecraft","mojang",100),
("GTA V","rockstar",500),
("Portal","valve",200),
("GTA IV","rockstar",100)
]
deleteAllInstances :: Eq a => a -> [a] -> [a]
deleteAllInstances a (x:xs)
| a == x = rest
| otherwise = x : rest
where
rest = deleteAllInstances a xs
deleteAllInstances _ _ = []
所以我想让deleteAllInstances
删除所有匹配项。
例如,如果我执行了deleteAllInstances "rockstar"
,它应该返回一个元组列表[("Minecraft","mojang",100),("Portal","valve",200),]
,并删除所有“rockstar”实例。
所以问题是如何让deleteAllInstances
删除“rockstar”和所有相关值并输出结果?
答案 0 :(得分:6)
您可能应该使用filter
。
filter :: (a -> Bool) -> [a] -> [a]
会在列表中运行,并保留谓词映射到True
的元素。
在这种情况下,你需要这样的东西:
deleteAllInstances :: String -> [Games] -> [Games]
deleteAllInstances string games = filter (\(_,s,_) -> (s /= string)) games
这里没有真正需要围绕filter
构建另一个函数,而且直接使用filter
代码可能更具可读性。
你不是直接在这里使用递归,而是由filter
抽象,它本身就是一个递归函数。递归的许多常见用法都包含在filter
,map
和fold
函数的组合中。
答案 1 :(得分:1)
这似乎是家庭作业,所以我会给你一些提示,而不是一个完整的解决方案。您的deleteAllInstances函数,因为它当前已编码,要求您传递整个三元组以匹配,而不是其中的字符串。如果您希望函数根据三元组第二位的字符串进行匹配和过滤,则可以在为函数定义参数匹配时将列表解构为三元组的级别(您可以阅读更多内容)关于参数匹配和类型解构这里:http://learnyouahaskell.com/syntax-in-functions)。
但是这可以通过使用地图和过滤器在Haskell中简单地实现,因此显式递归不是解决此问题的最惯用方法。
答案 2 :(得分:1)
以下是如何修改程序以执行您所描述的操作:
type Games = (String, String, Int)
test :: [Games]
test =
[
("Minecraft","mojang",100),
("GTA V","rockstar",500),
("Portal","valve",200),
("GTA IV","rockstar",100)
]
deleteAllInstances :: String -> [Games] -> [Games]
deleteAllInstances a (x:xs)
| a == x2 = rest
| otherwise = x : rest
where
(x1,x2,x3) = x
rest = deleteAllInstances a xs
deleteAllInstances _ _ = []
输出:
*Main> deleteAllInstances "rockstar" test
[("Minecraft","mojang",100),("Portal","valve",200)]