我想定义一个Haskell函数,该函数从字符串列表中删除一对字符串中包含的任何字符串,并仅返回包含所有剩余字符串的列表。所以一个例子是:
function ["football","basketball","soccer"] ("football", "basketball") = ["soccer"]
我知道您可以使用filter
函数来过滤满足给定谓词的列表。我知道我可以这样过滤出一个列表:
function' xs s = filter (/=s) xs
但我无法弄清楚如何使用元组。我运行代码时不断出错。知道怎么做吗?感谢
答案 0 :(得分:2)
更通用的解决方案是使用字符串列表来过滤而不是仅仅一对。更通用的解决方案是使用支持Eq
而不仅仅是字符串的任何内容列表。
所以,我们正在寻找类型为:
的东西Eq a => [a] -> [a] -> [a]
快速搜索hoogle产生(\\)
import Data.List ((\\))
main = print $ ["football","basketball","soccer"] \\ ["football", "basketball"]
答案 1 :(得分:1)
myfunc :: Eq a => [a] -> (a, a) -> [a]
myfunc xs (a,b) = filter (\x -> (x /= a) && (x /= b)) xs
让我们看一下filter
filter :: (a -> Bool) -> [a] -> [a]
执行filter f xs
时,
它只是在列表的所有元素上应用类型f
的函数a -> Bool
,删除此函数返回的False
。
我将元组元素上的模式匹配为(a,b)
,我将函数f
定义为\x -> (x /= a) && (x /= b)
。这是一个匿名函数,它接受列表的元素并仅在它既不等于元组的第一个元素也不等于第二个元素时返回True
。 &&
是布尔值and
,因此只有当它的两个参数都是True
时才返回True
。
答案 2 :(得分:1)
最直接的方法是运行过滤器两次,就像这样。
tupleFilter :: (Eq a) => [a] -> (a, a) -> [a]
tupleFilter xs (a, b) = function' (function' xs a) b
这里的关键是你在使用过滤器中的元素之前对你的元组进行模式匹配(或以其他方式解构)。
这是一个没有中间过滤功能的版本,在这种情况下可能应该内联以便将来阅读。
tupleFilter xs (a, b) = filter (\x -> (x /= a) && (x /= b)) xs