2017-10-08 15 views
2

だから私は私のリストから、「n」は最初の要素、「(B:BS)を得、この関数を作成した。関数take6エラーの非網羅的なパターン?

1 module Sexta where 
2 
3 take6::Int->[a]->[a] 
4 take6 n (b:bs) = if n<=0 then [] 
5     else [b] ++ (take6 (n-1) bs) 

問題は、私がしようとしたときということです:take6 2 []、それは示しています

*** Exception: sexta.hs:(4,1)-(6,15): Non-exhaustive patterns in function take6 

私は私が手でこれをしようとすると、cuzのは、なぜいけない:。

take6 2 [] 
    = [] ++take6 1 [] 
    = [] ++[]++take6 0 [] 
    = [] ++[]++[] 
    = [] 

答えて

3

take6 n (b:bs) = ... 

しかし、ここでは、このように、リストの「短所」コンストラクタですパターン(b:bs)を使用しています。 consコンストラクタは、先頭にb、末尾にはbsをとります。リストタイプには2つのコンストラクタがあります:ここですでに説明した "cons"と空のリスト[]です。 Haskellは第2引数の空のリストパターンの節を見つけることができないと訴えています。だからあなたの関数は形で定義する必要があります:

take6 n [] = ... 
take6 n (b:bs) = ... 

ここで問題はまだ何をするかです。あなたはおそらくそう、空のリストを返すようにしたいので、関係なく、私たちは空のリストの場合に取るものの、私たちは、もはや任意の要素を放出することはできません。

take6 _ [] = [] 

さらに、あなたは確か未満であることnの区別を作ります

take6 n (b:bs) | n <= 0 = [] 

しかし場合n > 0もある:又はゼロに等しいその場合、結果は空のリストです。その場合は、実際にtake6 (n-1) bsbを追加します。

または全額:

take6 :: Int -> [a] -> [a] 
take6 _ [] = [] 
take6 n (b:bs) | n <= 0 = [] 
       | otherwise = b : take6 (n-1) bs 
+0

はい、その潜在的に、より効率的な先頭に追加するためのより効率的な方法ということが気にし、再び「短所」コンストラクタを使用しています。しかし、最適化を有効にしてGHCを実行すると、それらは同じになるはずです。私はこの例をチェックしていませんが、リテラルリストを 'build'フォームに置く特別なルールがあります。これは'(++) 'の' foldr'フォームと融合するべきです。この場合、この最適化に依存する点はありませんが、 '[a]'を 'foldMap'のモノオイドターゲットとして使用すると、より重要と思われます。 – dfeuer

2

パターンb:bsは空のリストと一致していないあなたはヘクタールに別々のケースを必要とします空のリストを取り除く。

2

nをチェックする前にリストを破壊しているので、0であってもリストは空でなければなりません。あなたはそのケースを処理するためにガードを使用することができますが、リストが短すぎる場合にはこのことは役に立ちません。あなたが書いたプログラムで

関連する問題