简体   繁体   English

在列表上使用 Haskell 中的翻转和过滤功能

[英]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) ,所以我们可以翻转xsys

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM