在列表上使用haskell中的flip和filter函数
一个哈斯凯尔新手,如果这是一个相当基本的问题,我道歉。我想写一个函数,它接受两个变量列表,然后返回第一个列表,并从第二个列表中删除所有变量。例如,我想要以下输出 *Main>filterVariables[“y”、“z”、“a1”、“a2”][“y”、“a1”、“a3”] [“z”,“a2”] 这就是我迄今为止所写的:在列表上使用haskell中的flip和filter函数,haskell,Haskell,一个哈斯凯尔新手,如果这是一个相当基本的问题,我道歉。我想写一个函数,它接受两个变量列表,然后返回第一个列表,并从第二个列表中删除所有变量。例如,我想要以下输出 *Main>filterVariables[“y”、“z”、“a1”、“a2”][“y”、“a1”、“a3”] [“z”,“a2”] 这就是我迄今为止所写的: type Var = String data Term = Variable Var | Lambda Var Term | Apply Term
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)
我收到以下错误消息:
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 :: Eq => [a] -> [a] -> [a]
filterVariables items lst = filter (`notElem` lst) items
你不能在filter(`notElem`lst)
上flip
,因为filter(
notElemlst)
有类型[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)
filterVariables::(可折叠的t,等式a)=>[a]->ta->[a]
filterVariables=flip(filter.flip notElem)
实际上,这里是
过滤器。flip notElem
具有类型过滤器。flip notElem::(Eq a,Foldable t)=>ta->[a]->[a]
,因为它相当于\xs->filter(flip notElem xs)ys
或更短的\xs->filter(`notElem`xs)
,所以我们可以翻转xs
和ys
flip
函数采用两个输入的参数函数。因此,如果要将参数翻转到filterVariables
,则必须以两个参数的形式将其转换为flip
it。在您的版本中:
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 items lst=filter(`notElem`lst)items
?还有一个库函数,Data.List.(\\)
,您可以将其翻转到心底。还有l:[]
=[l]
。您将把\\放在哪里?
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