2012-04-29 9 views
13

質問1ハスケル:GHCiの中にエラー・メッセージ「には、インスタンスを」理解していない

こんにちは、WinGHCiに私が意図的に次のコードの間違った部分を行う場合:

3 4 

を次にエラーメッセージI取得は

<interactive>:1:1: 
    No instance for (Num (a0 -> t0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a0 -> t0)) 
    In the expression: 3 
    In the expression: 3 4 
    In an equation for `it': it = 3 4 

No instance for (Num (a0 -> t0))はどういう意味ですか?

質問2

なぜ次のコード:

(+) 2 3 4 
<interactive>:1:7: 
    No instance for (Num (a0 -> t0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a0 -> t0)) 
    In the second argument of `(+)', namely `3' 
    In the expression: (+) 2 3 4 
    In an equation for `it': it = (+) 2 3 4 

収率コードの第2部分からわずかに異なるエラー:最初のすなわち

2+3 4 
<interactive>:1:3: 
    No instance for (Num (a1 -> a0)) 
     arising from the literal `3' 
    Possible fix: add an instance declaration for (Num (a1 -> a0)) 
    In the expression: 3 
    In the second argument of `(+)', namely `3 4' 
    In the expression: 2 + 3 4 

コードの部分にはNo instance for (Num (a0 -> t0))があり、コードの2番目の部分にはNo instance for (Num (a1 -> a0))があります。


を[応答がehirdする](質問の回答のコメントから移動):

1)私は後者の2つの式が異なっている感謝していますが、私は理解しようとしないことを言っていますなぜ通訳者が前者には(Num (a0 -> t0))、後者には(Num(a1 -> a0))を選んだのでしょうか?

2)こんにちは、前者では、「機能のためのNumインスタンスはありません」と言いますとどういう意味ですか?申し訳ありませんが、インスタンスの概念が何であるかはっきりしていません。さらに好奇心の外に、インスタンスNum (a -> b)を使用して何らかの理由で通訳者に3 44 modulo 3と解釈させることができますか?

答えて

16

私の意図は、もう少し説明して、あなたの答えを補うことです。あなたが表現

3 4 

を書いたときにHaskellのインタプリタを使用すると、4が何であれに機能3を適用しようとしていると思います。 Haskellは関数として3を解釈するためには、それは整数3から機能(タイプa -> bのすなわち何か)を得るために機能

fromInteger :: Integer -> (a -> b) 

への呼び出しを行う必要があります。さて、fromIntegerはあなたがタイプxNumクラスのインスタンスを作成する際に、署名

instance Num x where 
    fromInteger :: Integer -> x 

すなわちを持っているNum型クラスで定義されている、あなたはに整数リテラルを変換する方法はHaskellを伝えfromIntegerの実装を与えますx。あなたの場合、xは関数タイプa -> bです。だからそれをやろう!


まず、いくつかの定型文。 Numハスケルのxインスタンスを作成するには、我々はまた、それShowEqのインスタンスにすることが必要です:

instance Show (a -> b) where show f = "<function>" 
instance Eq (a -> b) where f == g = False 

今度は、私たちは「4剰余3」として3 4を解釈したいとしましょう。次に、Haskellにmodを呼び出す関数として整数を解釈する方法を伝える必要があります。我々は(+)の実装を与える必要がmake an instance of Num

instance (Integral a, Integral b) => Num (a -> b) where 

(-):また、modためのみ整数型(それが署名mod :: Integral a => a -> a -> aを有する)、我々は同様に一体にabの種類を制限する必要を受け付け、(*)fromIntegral(実際には2つの他の関数も定義する必要がありますが、今はそれを心配しないでください)。あなたは2つの機能を追加した場合、すなわち、加算、減算、乗算(ここからすべてのコードがNumインスタンスの一部を形成し、インスタンス宣言に対してインデントされなければならない)

f + g = \x -> f x + g x 
    f - g = \x -> f x - g x 
    f * g = \x -> f x * g x 

を定義するために、かなり自然な方法があります

fgの場合、その引数にfgの両方を適用し、それらを一緒に追加する新しい関数が得られます。 fgを適用した結果は整数型である必要があったため、出力を加算することが理にかなっています。関数として我々は整数nを持っているとき、私たちが呼ばれたとき、両方の引数が同じであることを保証し、というパラメータmの機能を返す

fromInteger n = \m -> fromIntegral m `mod` fromIntegral n 

すなわちを書くことができ整数を解釈するために

(両方ともfromIntegralを呼び出して)、それらを関数modの引数として使用します。Haskellの不満を停止する

最後に、もう少し定型:

abs f = undefined 
    signum f = undefined 

我々はこれを試すことができます。 numfun.hsというファイルに自分のコードがあります。私はHaskellのインタプリタを起動し、私のファイルをロードします。

Prelude> :l numfun.hs 
[1 of 1] Compiling Main    (numfun.hs, interpreted) 
Ok, modules loaded: Main. 

を今、私はいくつかの関数を定義することができます。

*Main> let f = (+ 1) 
*Main> let g = (* 2) 

私はそれらを追加したり、それらを引くことができます。

*Main> (f + g) 3 -- (3+1) + (3*2) 
10 
*Main> (f - g) 3 -- (3+1) - (3*2) 
-2 

そして、私がすることができます電話番号を関数として呼び出します。

*Main> 3 4   -- 4 `mod` 3 
1 
+0

うわあ、この詳細でよく説明された説明をありがとうございました。ほんとうにありがとう。私は、あなたが書いたものをすべて消化する前に、Haskellのウェブサイトで指定された書籍のいくつかをヒットし、あなたの記事にもう一度戻ってくる必要があると思います。ありがとうございました。 – artella

14

4のような整数リテラルは、Numインスタンスを持つ任意のタイプである可能性があるため、最初のエラーが発生します。それはあなたが引数(4)に3を適用しているので、それは、IntegerとしてDoubleRationalなどにサービスを提供できるよう4は、タイプ(Num a) => aを持っている、である、それは(文脈で、3は関数型でなければならない、ということを知っていますすなわち、a0およびt0についてはa0 -> t0)。しかし、関数にはNumインスタンスがないため、3の関数としての使用は無効です。 instance Num (a -> b)を追加した場合はうまくいくが、そうしたくないと思われる。

後者の場合、2つのエラーメッセージは同等です。 GHCによって生成された名前は特に意味を持ちません。文字は、通常、使用している関数の型の型変数から派生しています。数字はあいまいではありません。この場合、2番目の式は(+) 2 (3 4)に相当します(関数アプリケーションは任意の中置演算子よりも厳密にバインドされるため)。これはコードの最初の部分と全く同じではありません。

+0

こんにちは後者の2つの表現は異なっていますが、通訳者が前者に '(Num(a0 - > t0))'を、通訳者に '(Num(a1 - > a0))'を選んだ理由を理解しようとしてはいけないと言っていますか?彼らは異なっているという事実の他に、後者?ありがとう。 – artella

+0

こんにちは、前者の場合、「関数のNumインスタンスはありません」とはどういう意味ですか?申し訳ありませんが、インスタンスの概念が何であるかはっきりしていません。 さらに、好奇心の外に、あなたの 'インスタンスNum(a - > b)'メソッドを使って、 '3 4 'を' 4 modulo 3 'と解釈するように通訳者に何と言ってもいいですか?ありがとうございました – artella

関連する問題