2017-03-14 14 views
0

私はHaskellの初心者です。リストの最後に要素を追加しようとしています。Haskellのリストの最後に要素を追加します。

[1,2,3,4]と数字10のようなリストを入力します。この[1,2,3,4,10]のような出力が必要です。

マイコード:

func a [] = a 
func a (x:xs) = x : func a (x:xs) 

しかし、私はそのエラーを取得しています:

Non type-variable argument in the constraint: Num [a] 
(Use FlexibleContexts to permit this) 
When checking that ‘it’ has the inferred type 
it :: forall a. (Num a, Num [a]) => [a] 

は、誰もが説明を助けることはできますか?

+0

リストの最後に項目を追加するのは良い練習ですが、通常は本物のHaskellプログラムで行うべきではありません。それは高価で、間違った順序でリストを構築していることを示します。通常、より良いアプローチがあります。 – amalloy

+0

それは大学のための唯一の練習です:) – Darius

答えて

1

あなたは何が起こっていることを理解する必要があります等号の左側にある関数の定義は「パターンマッチング」です。あなたは基本的に私は最初のパラメータとして、すなわちa、任意の型の要素を受け入れるように最初、2番目のパラメータとして空のリスト、すなわち[]たい

func a [] = a 
... 

を言っている次の文では

、 。その場合、aを返すことにします。問題は、あなたがリスト[a]を返そうとしていることです(あなたはこの答えの後半に理由を見るでしょう)。

関数定義の2番目の部分(これは、最初の "パターン"が入力と一致していないことを意味します)は、次のように言います:任意の型の要素、つまりaと空でないリストすなわち、(x:xs)(x:xs)は言うことができます:はい、私はリストを持っており、xはそのリストの最初の要素です。リストの残りの部分はxsと呼ばれ、空でもかまいません。その場合、元のリストはサイズ1のリストになります。つまり、ちょうど[x]です。どのようなパターンが一致した場合は、返却すると、あなたが二番目のパラメータ(すなわちx)として渡されたリストの最初の要素を取り、それを先頭に追加していることを意味し

... = x : func a (x:xs) 

ある

... 
func a (x:xs) = x : func a (x:xs) 

func a (x:xs)の結果です。

func a [] = [a] 
func a (x:xs) = x : func a xs 

私はここに二つのことを注意したいと思います:あなたのこの問題の説明を考えると

、ここでの可能な解決策です。最初のパターン、つまりfunc a [] = [a]では、リスト、つまり[a]が返されます。第2のパターンでは、私はxsfuncに、すなわちfunc a xsに渡します。どちらの場合も、私はリストを返します!

これはなぜ機能しますか?例を見てみましょう。例えば、funcfunc 3 [1, 2]のように呼んだとします。そして、これが起こります。

[1, 2]は空のリストではないので、最初のパターンと一致しないので、2番目のパターンを見てみましょう。はい、私たちは2番目のものとマッチします。今度はa = 3,x = 1(リストの先頭)とxs = [2]があります。そこで、我々は1 : func 3 [2]を持っています。だから我々は繰り返す!現在、a = 3(前と同じ)、x = 2およびxs = [](つまり空のリスト)があります。そこで関数本体を進め、2 : func 3 []を実行します。最後にfunc 3 []が最初のパターンと一致し、[3]を返します。しかし何に?さて、2 : [3]には、何に戻る? 1 : 2 : [3]に。

1

は比較:

func a (x:xs) = x : func a (x:xs) 
     --  ^^^^^^^^^^^^^^^^^ returns a list 
func a [] = a 
     --^returns a non-list 

したがって、型エラーを。おそらく[a]またはa : []が代わりに必要です。

(あなたがそれに再びリスト全体x:xsを渡すので、再帰呼び出しは、間違っている。リストには、基本ケースに到達することはありません、他の小さい取得する必要があります。)

関連する問題