[英]Using the flip and filter functions in haskell on a list
a Haskell newby, so apologies if this is a rather basic question.一个 Haskell 新手,如果这是一个相当基本的问题,那么抱歉。 I want to write a function which takes two lists of variables and returns the first with all variables from the second list removed from it.
我想编写一个函数,它接受两个变量列表并返回第一个,其中从第二个列表中删除了所有变量。 For example I want the following output
例如我想要以下输出
*Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"] *Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"]
["z","a2"] ["z","a2"]
This what I have written so far:这是我到目前为止所写的:
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)
I get the following ouput:我得到以下输出:
*Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"] *Main> filterVariables ["y","z","a1","a2"] ["y","a1","a3"]
["a3"] [“a3”]
Could the flip function be used here?这里可以使用翻转功能吗?
When I write:当我写:
filterVariables lst = flip (filter ( `notElem` lst))
I get this error message:我收到此错误消息:
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))
How do I use flip correctly?我如何正确使用翻转? Or can you suggest another method?
或者你能建议另一种方法吗?
The flip
function takes an argument function of two inputs. flip
函数采用两个输入的参数函数。 So if you want to flip the arguments to filterVariables
, you have to flip
it in a form that takes two arguments.因此,如果您想将参数翻转为
filterVariables
,则必须以带有两个参数的形式flip
它。 In your version:在您的版本中:
filterVariables lst = flip (filter ( `notElem` lst))
you have already accepted one argument, and only one remains to accept.你已经接受了一个论点,只剩下一个要接受。 We can fix this by first moving the
lst
argument to the other side of the equality:我们可以通过首先将
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
I think it might be simpler to write this as:我认为将其写为以下内容可能更简单:
filterVariables :: Eq => [a] -> [a] -> [a]
filterVariables items lst = filter (`notElem` lst) items
You can not flip
on filter (`notElem` lst)
since, filter (
notElem lst)
has type [a] -> [a]
, and flip
has type flip :: (b -> a -> c) -> a -> b -> c
.您不能
flip
filter (`notElem` lst)
因为filter (
notElem lst)
类型为[a] -> [a]
,而flip
类型为flip :: (b -> a -> c) -> a -> b -> c
。 This thus should mean that [a] -> [a]
is the same type as b -> a -> c
, but that implies that [a]
and a -> c
are the same type.因此,这应该意味着
[a] -> [a]
与b -> a -> c
类型相同,但这意味着[a]
和a -> c
是相同的类型。
You can however make use of flip
by implementing a point-free variant:但是,您可以通过实现无点变体来使用
flip
:
filterVariables :: (Foldable t, Eq a) => [a] -> t a -> [a]
filterVariables =flip (
filter . flip notElem)
Indeed, here filter . flip notElem
确实,这里是
filter . flip notElem
filter . flip notElem
has type filter . flip notElem :: (Eq a, Foldable t) => ta -> [a] -> [a]
filter . flip notElem
具有类型filter . flip notElem :: (Eq a, Foldable t) => ta -> [a] -> [a]
filter . flip notElem :: (Eq a, Foldable t) => ta -> [a] -> [a]
since it is equivalent to \\xs ys -> filter (flip notElem xs) ys
or shorter \\xs -> filter (`notElem` xs)
, so we can then flip xs
and ys
. 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.