2016-11-12 8 views
-3

私は、次の種類の機能を書いている:タプル評価

match :: [(String,a)] -> Maybe (String, a, a) 

私は関数はタプルのリストをトラバースし、の最初の要素(文字列)任意のタプルがあるかどうかを決定します同じです。もしそうなら、私はその文字列を含むタプルと、一致するタプルのそれぞれの2番目の要素を返したいと思います。一致するタプルがない場合は、 "Nothing"を返します。複数の一致がある場合は、最初に見つかったものを返します。例えば

match [("x", 3), ("y", 4), ("z", "5"), ("x", 6)] = ("x", 3, 6) 
match [("x", 3), ("y", 4), ("z", "5")] = Nothing 

私は考えている:

match (x:xs) = if (fst x) = (fst xs) return (fst x, snd x, snd xs) 
--if no matches, return Nothing 

は、任意の助けをありがとう!

+0

( "z"、 "5")は誤植であると仮定します。他の数字には引用符がありません。 –

答えて

2

「x」のタプルが3つまたは4つある場合はどうなりますか?可変長のタプルを持つことはできません。リストを返すこともできます:

match :: [(String, a)] -> Maybe (String, [a]) 

一致するタプルが複数ある場合はどうなりますか?あなたはそれらすべてを望んでいますか、まさに最初のものか?あなたがそれらをすべて望むなら、あなたは一致のリストを返すべきです。あなたはこのようにそれを考える場合

match :: [(String, a)] -> [(String, [a])] 

は、あなたは一緒にすべての「x」のペアをグループ化することを確認することができ、および「Y」のペア、というように、良いスタートになります。あなたは

sortBy (comparing fst) xs 

comparing、機能と2つの値をとり、それぞれに関数を適用し、結果を比較を使用することによってこれを行うことができます。 sortByは、最初の引数を比較関数として使用します。したがって、sortBy (comparing fst)は、リストを各タプルの最初の要素で並べ替えます。

次に、groupByを使用して要素をまとめて収集できます。

編集:

groupBy

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

だからあなたは、パラメータとしてそれを与えるために機能equalFirstを書く必要があるタイプがあります。それでは

groupBy equalFirst $ sortBy (comparing fst) xs 

はあなたのリストのリストである

[[("x", 3), ("x", 6)], [("y", 4)], [("z", 5)]] 

を与えるだろう。各サブリストには同じ文字のタプルが含まれています。

これらのサブリストの1つを取り、必要な結果に変換する関数を書くことができます。その後、mapを使用してリストのリストに適用します。

+0

この関数では、一致するタプルが1つしかなく、2つのタプルに "x"があると仮定します。 –

+0

@ Sarah.S:パターンマッチングを使用して、結果のリストから必要な3要素タプルに変換します。 –