[英]Using the flip and filter functions in haskell on a list
一个 Haskell 新手,如果这是一个相当基本的问题,那么抱歉。 我想编写一个函数,它接受两个变量列表并返回第一个,其中从第二个列表中删除了所有变量。 例如我想要以下输出
*Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"]
["z","a2"]
这是我到目前为止所写的:
type Var = String
data Term =
Variable Var
| Lambda Var Term
| Apply Term Term
variables :: [Var]
variables = [l:[] | l <- ['a'..'z']] ++ [l:show x | x <- [1..], l <- ['a'..'z']]
--works but the wrong way around!!!
filterVariables :: [Var] -> [Var] -> [Var]
filterVariables lst = filter ( `notElem` lst)
我得到以下输出:
*Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"]
[“a3”]
这里可以使用翻转功能吗?
当我写:
filterVariables lst = flip (filter ( `notElem` lst))
我收到此错误消息:
Couldn't match type ‘[Var]’ with ‘[Var] -> c0’
Expected type: [Var] -> [Var] -> c0
Actual type: [Var] -> [Var]
• Possible cause: ‘filter’ is applied to too many arguments
In the first argument of ‘flip’, namely ‘(filter (`notElem` lst))’
In the expression: flip (filter (`notElem` lst))
In an equation for ‘filterVariables’:
filterVariables lst = flip (filter (`notElem` lst))
我如何正确使用翻转? 或者你能建议另一种方法吗?
flip
函数采用两个输入的参数函数。 因此,如果您想将参数翻转为filterVariables
,则必须以带有两个参数的形式flip
它。 在您的版本中:
filterVariables lst = flip (filter ( `notElem` lst))
你已经接受了一个论点,只剩下一个要接受。 我们可以通过首先将lst
参数移到等式的另一侧来解决这个问题:
filterVariables lst = filter ( `notElem` lst) -- original, accepts one more argument
filterVariables = \lst -> filter (`notElem` lst) -- now a function which accepts two arguments
filterVariables = flip (\lst -> filter (`notElem` lst)) -- flipped form
我认为将其写为以下内容可能更简单:
filterVariables :: Eq => [a] -> [a] -> [a]
filterVariables items lst = filter (`notElem` lst) items
您不能flip
filter (`notElem` lst)
因为filter (
notElem lst)
类型为[a] -> [a]
,而flip
类型为flip :: (b -> a -> c) -> a -> b -> c
。 因此,这应该意味着[a] -> [a]
与b -> a -> c
类型相同,但这意味着[a]
和a -> c
是相同的类型。
但是,您可以通过实现无点变体来使用flip
:
filterVariables :: (Foldable t, Eq a) => [a] -> t a -> [a]
filterVariables =flip (filter . flip notElem)
确实,这里是filter . flip notElem
filter . flip notElem
具有类型filter . flip notElem :: (Eq a, Foldable t) => ta -> [a] -> [a]
filter . flip notElem :: (Eq a, Foldable t) => ta -> [a] -> [a]
因为它等价于\\xs ys -> filter (flip notElem xs) ys
或更短的\\xs -> filter (`notElem` xs)
,所以我们可以翻转xs
和ys
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.