2017-08-27 14 views
2

述語関数に基づいてフィルタリングする必要がある項目のリストがあります。述部関数は、結果を正常に戻すために複数の引き数を必要とします。複数の引数を取る述語を持つフィルタ

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

[[String]]をフィルタリングする必要がリストであり、そして人々の名前のリストです:

は、ここでフィルタリングされたリストを返す必要がある機能のために、私の関数型宣言です。人物の名前は、["FirstName", "MiddleName", "LastName"]と表されます。

[String]は、個人の名前です(例:["Bob", "Jane", "Alice"])。

私が必要としているのは、と少なくとも同じ名前のIntの番号を持たないすべての名前を除外することです。例えば

私は

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

をコールした場合["d", "e", "f"]["a", "f", "b"]と共通の少なくとも2名を持っていないので、私は

[["a", "b", "c"]]になるだろう。

私はこれをユーザーが人のリストを管理できるようにするより大きなプログラムの一部として使用する予定です。このプログラムの機能の1つは、名前で検索し、ユーザーが入力した整数パラメーターに基づいて名前が一致するすべてのユーザーのリストを返します。

私はfilter関数を知っていますが、述語関数の型はp :: Boolである必要があります。あなたが見ることができるように私の述語はより複雑です。

答えて

1

は少し周りの引数を移動しよう:

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

私が正しく質問を理解していれば、あなたは[[String]]をフィルタリングし、[[String]]を返すようにしたいです。今あなたがタイプ[String] -> Boolと機能を必要とし、

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

具体的には、この場合には、a[String]がある:それはタイプを持っている、filterとよく合います。

あなたは、しかし、それよりも多くのデータが必要なのか:一致の数、および名前を検索するために、これもこれらの引数を取る関数を書く:

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構文を使用してmyFilter関数内predを定義することができます。

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[(=="a"), (=="b"), (=="c")]のような応用的リストファンクタにasを変換しますし、我々は[True,False,False,False,False,True,False,False,False]結果、我々は真の値をフィルタし、それが>= nだかどうかを確認するために長さをチェックし[(=="a"), (=="b"), (=="c")] <*> ["a", "f", "b"]ようbsのすべての項目に応用可能で、各機能を適用します。

私はそれがはっきりしていることを望みます。

関連する問題