2013-04-07 17 views
5

私はハスケルを学ぶようになりました。私は理由を見つけることができない奇妙な間違いをした。私が入力したときにハスケルの関数定義

No instance for (Num [Char]) 
arising from the literal `3' 
Possible fix: add an instance declaration for (Num [Char]) 
In the second argument of `(<)', namely `(3)' 
In the expression: x < (3) 
In the expression: if x < (3) then "bang" else "boom" 

:しかし

let xs = [if x < 3 then "bang" else "boom" | x <- xs] 

そして、GHCiの中のエラーのテキスト:ここ

は、私が入力したコードである

ある
let boom xs = [if x < 3 then "bang" else "boom" | x <- xs] 

本の例では、私は何の問題もない。

誰かが私の間違いを説明できますか?

+0

あなたのお返事ありがとうございます。彼らはお互いを補完する。 – guillaume8375

答えて

7

式をa型にしてみてください。

xs = [if x < 3 then "bang" else "boom" | x <- xs] 

のでxsがリストされ、我々はその要素が持っているものを入力し、まだわかりませんので、ですので、次を見てみましょう。リスト要素は、タイプString(別名[Char])の発現である

if x < 3 then "bang" else "boom" 

あります。

従って。リスト要素を記述する式からxリストxs自体から取り出されるので、従って、それが多型であり、3は整数リテラルである、あまりにStringであり、そして

if x < 3 

今比較に使用されています表現x < 3からそう

3 :: Num a => a 

を入力している、我々は持っている

  • リテラルからの制約である
  • StringxStringのリストから引き出されているという事実からの制約。

Stringには、タイプが豊富な表現を使用するために、Numのインスタンスが必要です。

通常、Stringの場合はNumインスタンスはありません(有用なものはどのように見えますか?)ので、タイプエラーが発生します。

xsは、関数の引数である場合は、xの種類が動作するため、Stringする必要がありますない理由は

boom xs = [if x < 3 then "bang" else "boom" | x <- xs] 

はありません。

+0

お返事ありがとうございました。彼らはお互いを補完する。 – guillaume8375

13

xsの定義は再帰的です。つまり、独自の定義内にxsを使用しています。私はそれがあなたが意図したものだとは思わない。

あなたはリスト内包内部"bang""boom"を使用しているので、Haskellは(xsは、リスト内包の結果に等しいため)xsは、文字列のリストでなければならないことを知っています。さらに、xxsx <- xs)の要素であるため、xは文字列(a.k.a. [Char])である必要があります。ただし、x < 3を実行します。つまり、xは数字です。エラーメッセージは、 "文字列は数字ではありません"を意味します。

+0

ダーン、数秒で私を倒してください。+1 – jozefg

+0

タイプエラーの素敵な簡潔な説明 – Wes

0
let xs = ... 

は、xsは「ビッグバン」sおよび/または「ブーム」のリストを等しく意味するが、条件は、これらの要素は、通常は数字ではなく文字列で行われ< 3、のためにテストされるべきであると述べています。

let boom xs =... 

パラメータ「XS」は< 3について試験されるべき要素が描画されるリストである方程式の右辺の関数「ブーム」等しいです。