学習の素材は、
すごいHaskellたのしく学ぼう!
この表記は、私見・感想です。
Num
のインスタンスは当然のように等値比較できると思っていたが
サンプルコードを試していると、手本どおりにもかかわらずエラーになるプログラムがあった。
finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfValue, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfValue, finalGen)
これは有限のリストと乱数ジェネレータを返す関数だが、このままGHCiにロードしようとすると、
randomTest.hs:14:15:
Could not deduce (Eq n) arising from the literal ‘0’
from the context (RandomGen g, Random a, Num n)
bound by the type signature for
finiteRandoms :: (RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
at randomTest.hs:13:18-69
Possible fix:
add (Eq n) to the context of
the type signature for
finiteRandoms :: (RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
In the pattern: 0
In an equation for ‘finiteRandoms’: finiteRandoms 0 gen = ([], gen)
Failed, modules loaded: none.
といったエラーがでた。
リテラルの0
をパターンマッチで使っているが、型制約を見てもEq
型クラスであることを推論できなかった、という内容となっている。
Num
は等値比較を要件としていない 。したがって、パターンマッチに数値リテラルを使うならば、その型はEq
のインスタンスでなくてはならない。この場合はEq a
という型制約を追加すると、エラーを解消することができる。
参考サイト
stackoverflow:Haskell error: “Could not deduce (Eq a) arising from the literal ‘0’”