2017-08-27 85 views
2

我有一個需要根據謂詞函數進行過濾的項目列表。謂詞函數需要多個參數才能成功返回結果。過濾一個帶有多個參數的謂詞

這裏是我的功能類型聲明,對於需要返回過濾列表的功能:

myFilter :: Int -> [[String]] -> [String] -> [[String]]

[[String]]是需要被過濾列表,是人的名單。一個人的名字表示如下["FirstName", "MiddleName", "LastName"]

[String]是個體的名稱,例如["Bob", "Jane", "Alice"]

我需要的是要過濾掉所有名稱中沒有至少具有與個人名稱相同名稱的號碼

例如,如果我打電話給

myFilter 2 [["a", "b", "c"],["d", "e", "f"]] ["a", "f", "b"]

我會得到

[["a", "b", "c"]]因爲["d", "e", "f"]不具有共同的至少2名與["a", "f", "b"]

我打算將此作爲更大程序的一部分,允許用戶管理一個人員列表。該程序的功能之一是按姓名進行搜索,根據用戶輸入的整數參數返回所有名稱匹配人員的列表。

我知道filter函數,但似乎謂詞函數應該只能是p :: Bool類型。正如你所看到的,我的謂詞更復雜。

回答

1

試着走動了一下參數:

myFilter :: Int -> [String] -> [[String]] -> [[String]] 

如果我理解正確的問題,要篩選[[String]]並返回[[String]]。與filter非常適合,它的類型是:

filter :: (a -> Bool) -> [a] -> [a] 

具體而言,在這種情況下,a[String],所以現在你需要的功能與類型[String] -> Bool

你這樣做,但是,需要更多的數據:搜索匹配的數量和名稱,因此編寫一個函數,也有這些參數:

pred :: Int -> [String] -> [String] -> Bool 

現在,您可以部分申請pred您想要搜索的值,例如(pred 2 ["a", "f", "b"])。該功能將具有類型[String] -> Bool,它符合filter的要求。

換句話說,你應該能夠編寫這樣的事:

myFilter i target names = filter (pred i target) names 

可以,如果你想使用where關鍵字,或使用let..in語法定義predmyFilter函數內。

0

我猜你可能會這樣做;

myFilter :: Int -> [[String]] -> [String] -> [[String]] 
myFilter n ass bs = filter (\as -> n <= length (filter (True ==) ((==) <$> as <*> bs))) ass 

*Main> myFilter 2 [["a", "b", "c"],["d", "e", "f"]] ["a", "f", "b"] 
[["a","b","c"]] 

所以as[[String]]列表中的每個項目。

(==) <$> as <*> bs)部分作品喜歡; (==) <$> as會轉換成as一個適用函子列表像[(=="a"), (=="b"), (=="c")],然後我們在應用性應用每一個功能,像[(=="a"), (=="b"), (=="c")] <*> ["a", "f", "b"]bs每一個項目,這導致[True,False,False,False,False,True,False,False,False],我們篩選真值,並檢查長度,看它是否是>= n

我希望很清楚。