0

我想定义一个 Haskell 函数,它从字符串列表中删除一对字符串中包含的任何字符串,并只返回一个包含所有剩余字符串的列表。所以一个例子是:

function ["football","basketball","soccer"] ("football", "basketball") = ["soccer"]

我知道您可以使用该filter函数来过滤满足给定谓词的列表。我知道我可以通过这种方式过滤掉一个列表:

function' xs s = filter (/=s) xs

但我不知道如何让它与元组一起工作。运行代码时,我不断收到错误。知道怎么做吗?谢谢

4

3 回答 3

2

更通用的解决方案是使用一个字符串列表来过滤,而不仅仅是一对。一个更通用的解决方案将使用支持的任何内容的列表,Eq而不仅仅是字符串。

因此,我们正在寻找具有以下类型的东西:

Eq a => [a] -> [a] -> [a]

快速搜索 hoogle 产量(\\)

import Data.List ((\\))

main = print $ ["football","basketball","soccer"] \\ ["football", "basketball"]
于 2012-10-09T04:22:25.513 回答
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,它只是对列表的所有元素应用ftype 函数,a -> Bool删除那些该函数返回的元素False

我在元组的元素上进行了模式匹配,(a,b)并且我刚刚将函数定义f\x -> (x /= a) && (x /= b)。这是一个匿名函数,它接受列表中的一个元素,True仅当它既不等于元组的第一个元素也不等于第二个元素时才返回。&&是布尔值and,因此True仅当它的两个参数都是. 时才返回True

于 2012-10-09T03:52:59.733 回答
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
于 2012-10-09T04:06:32.690 回答