簡體   English   中英

在列表上使用 Haskell 中的翻轉和過濾功能

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM