我々はハイレベルで何をしなければならないかのチェックを考えるならば、我々はそれが参照するには、サンプルのすべての要素を確認する必要があります知っていますテスト "Sample3"に文字列の結果のいずれか(またはすべて、私はあなたが意味するものが不明)が含まれている場合。
だから我々は、我々が再帰を必要と知っていると我々は、機能の概要を作ることから始めることができます。
check :: String -> [String] -> [Sample] -> Bool
check samplename result [] = False
check samplename result (x:xs) = ...
リストが空であるときに、何の一致が私たちはすぐにfalseを返すことができます発生しないことができます。再帰的な場合、我々はxをチェックする必要があり、一致が見つからなければxsのチェックを続ける必要があることを知っている。これを行うための1つの可能な方法は、ヘルパー関数のチェック '(チェックインだけでインライン化することもできます)です。
check samplename result (x:xs) = check' x || check samplename result xs
where check' ...
大丈夫ですので、チェックは何ですか?データ型Sampleをチェックして、一致するものがあるかどうかを調べます。私たちは、サンプルが2つのコンストラクタ、Test1をとを持って知っているTest2をので
check' :: Sample -> Bool
check' (Test1 (name, values)) = ...
check' (Test2 (name, values)) = ...
私たちがしなければならない最初の事は、それがsamplenameと一致するかどうかを確認するために名前の値をテストしているように見えるはずです「チェック 。私たちは、簡単にチェックの子関数は、チェックで定義された変数がスコープ内にあるある「警備員のチェック以来
check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = ...
check' (Test2 (name, values)) | name == samplename = ...
check' _ = False
を使用してこれを行うことができますので、我々はそれらを参照することができます。名前が一致しないイベントを処理する新しいケースが追加されました。
これで、の結果のいずれか(またはすべて)の値がの値であるかどうかを確認することが考えられます。幸いなことに、プレリュードにはこれに使用できる機能があります。述語とリストのすべての要素をチェック
check :: String -> [String] -> [Sample] -> Bool
check samplename result [] = False
check samplename result (x:xs) = check' x || check samplename result xs
where check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
はプレリュードはのための標準的な機能を有するように一般的です:
elem :: Eq a => a -> [a] -> Bool
機能は現在、完全な機能は、このようにある
check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
なりこの。チェックを定義する1つの方法は、関数またはおよびマップを使用することです。 これは、一般的にいえあまり効率的機能をもたらすであろう。
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test1 (name, values)) | name == samplename = result `elem` values
check' (Test2 (name, values)) | name == samplename = result `elem` values
check' _ = False
機能は別の機能は、次に
なるよう
type ID = Int
type Name = String
type Values = [[String]]
data Sample = Test ID Name Values
ように、データ型のための代替的な構造を適合させることにより簡略化することができます
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test _ name values) | name == samplename = result `elem` values
check' _ = False
最後に、チェック 'の結果がブールであり、ガードもブールなので、リファクタリングチェックはできません。フォールスルーケース
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = or (map check' samples)
where check' :: Sample -> Bool
check' (Test _ name values) = name == samplename && result `elem` values
これは**または必要(マップを.. ..)**パターンは再びプレリュード機能これを行う任意のありますように一般的です。チェックをさらに簡素化することができます
check :: String -> [String] -> [Sample] -> Bool
check samplename result samples = any check' samples
where check' :: Sample -> Bool
check' (Test _ name values) = name == samplename && result `elem` values
'[String]'引数( "result")がどのように使われているのか分かりません。 – MatrixFrog
resultは、文字列「abort」を含むリストです。 – veda
コード・スタイル・ノート上。 'xならばTrue else else'は' x'と同じです。文字列 '' True ''と' 'False''を使うのは良い考えではありません。この場合、それらを完全にドロップし、単に 'True'と' False'を使用することができます。 'elem True xs'は' or xs'と同じです。 – HaskellElephant