2

Haskell のエラー メッセージは、初心者のプログラマにとって混乱を招くため、理解しようとしています。私が見つけることができる最も簡単な例はこれです:

Prelude> 1 + True
<interactive>:2:3:
No instance for (Num Bool)
  arising from a use of `+'
Possible fix: add an instance declaration for (Num Bool)
In the expression: 1 + True
In an equation for `it': it = 1 + True

パラメータの順序に関係なく、コンパイラが(Num Bool)を検索するのはなぜですか? 以下を定義した後に機能するのはなぜですか?

instance Num Bool where (+) a b = True;
[...]
Prelude> 1 + True
True

2 番目の引数が( Num Bool)の場合にのみ、(+)を(Num Bool)に適用できるようにするにはどうすればよいですか?

4

3 に答える 3

4

このエラー メッセージが表示されるのは、1との両方+がポリモーフィックであるためです。どちらも異なる型に対して機能する可能性があります。

見てみましょう:

Prelude> :t 1
1 :: Num a => a
Prelude> :t (+)
(+) :: Num a => a -> a -> a

したがって、1 の両方が、クラス内のどの型に対しても+意味を持ちます。したがって、 と書くと、インスタンスがあれば、実際には になる可能性があります。実際、自分でそれを行うことができます:Num1 + Bool1 BoolBoolNum

instance Num Bool where
  fromInteger x = x /= 0
  (+) = (&&)
  ...

これを行うと、1 + True実際に機能します。数値リテラルを bool として使用することもできます。

*Main> 1 :: Bool
True
*Main> 1 + True
True

これは、引数の順序に関係なく同じエラーが発生する理由も説明しています。コードの唯一の実際の問題は、True--if が機能した場合、他のすべても同様に機能することです。

于 2013-10-30T22:09:38.633 に答える
0

次のコマンドを実行すると、data Boolは のインスタンスではないというエラー メッセージが表示されます。class Numghci

Prelude> :info Num
class Num a where
  (+) :: a -> a -> a
  (*) :: a -> a -> a
  (-) :: a -> a -> a
  negate :: a -> a
  abs :: a -> a
  signum :: a -> a
  fromInteger :: Integer -> a
    -- Defined in `GHC.Num'
instance Num Integer -- Defined in `GHC.Num'
instance Num Int -- Defined in `GHC.Num'
instance Num Float -- Defined in `GHC.Float'
instance Num Double -- Defined in `GHC.Float'

a は、足し算、掛け算、引き算などNumができるものであることがわかります。(+)(*)(-)

はこのBoolように動作できないため、 のインスタンスがありませんNum。のインスタンスでのみ使用できるNo instance for (Num Bool)ため、エラーの行を説明しています(+)Num

で行っていることは、 a が a のように動作するようになったため、 aを加算、乗算などする方法を指定する必要がinstance Num Bool where (+) a b = Trueあると言っているということです。BoolNumBool(+)(*)

十分に簡単な方法で説明したことを願っています。

于 2013-10-30T22:09:27.370 に答える