从输入中删除元素 Haskell

Remove elements from input Haskell

我要制作功能remove :: String -> Char -> String 它删除了第二个参数中字符的所有实例 来自第一个参数中的字符串。例如:

remove "ab cd ef" ' ' == "abcdef"

remove "ab cd cf" 'c' == "ab d f"

我目前拥有的是:

remove (x:xs) y 
     | x == y     = xs
     | otherwise  = x : remove xs y

这只会删除一个元素,例如如果我写 remove "ab cd ef" ' ' 它打印出 "abcd ef" 而不是 "abcdef".

我需要使用递归创建一个函数,使用列表理解创建另一个函数。

正如 chi 在评论中指出的那样,您需要在两个分支中都使用递归,否则您最终只会删除第一个实例。

为完整起见,这里是正确的代码:

remove [] _ = []
remove (x:xs) y
     | x == y     = remove xs y
     | otherwise  = x : remove xs y

如果您不包括 [] 大小写,那么您将收到有关模式匹配的错误消息——这是因为当您匹配模式 (x:xs) 时,您假设数组的长度为>= 1 表示要定义的 x。如果您想到像 data List a = Cons a (List a) | Empty 这样的列表,那么任何采用列表的函数都必须在 ConsEmpty 构造函数上进行模式匹配。显然,如果您有一个空字符串,则没有任何内容可以删除,因此 [] 映射到所有 y.

[]

如果您也需要列表理解,请认识到列表理解是 mapfilter 的组合。我们不想改变 map 允许我们做的字符,只是过滤掉匹配 y.

的字符

语法 [f x | x <- xs, predicate x] 表示“从 xs 中取出每个 x,其中表达式 predicate xTrue,并且 return 是一个列表表达式 f xf xmap 部分,predicate x 是过滤器部分。

因此我们可以写成:

remove xs y = [x | x <- xs, x /= y]

注意这里我们没有模式匹配列表值构造函数,所以我们不需要两种情况。 x <- xs 部分仅表示如果输入列表为空,我们将得到 []。我们还使用了 xid x 而不是 f x,我们的谓词是 x /= y.

此外,仅供参考,此处不需要 template-haskell 标记,这是一种元编程语言扩展。