Numで等値比較できないというエラー(Haskell)
『すごいHaskell』を読んでいたら、次のコードでエラーが出た。
n個のランダムな値のリストを作成する関数
finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)
『すごいHaskell 楽しく学ぼう』p201
このリストを読み込むと、以下のようなエラーが出た。
chap09-01.hs:19:15: error:
• 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 :: forall g a n.
(RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
at chap09-01.hs:18:1-69
Possible fix:
add (Eq n) to the context of
the type signature for:
finiteRandoms :: forall g a n.
(RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
• In the pattern: 0
In an equation for ‘finiteRandoms’: finiteRandoms 0 gen = ([], gen)
|
19 | finiteRandoms 0 gen = ([], gen)
| ^
このエラーメッセージの意味が最初わからなかったのだが、次のページを見たら
内容がわかった。
エラーメッセージの意味
Could not deduce (Eq n) arising from the literal ‘0’
リテラル 0 から生じる (Eq n) を推測できませんでした。
–> (Num a) とすると、a は数であることが推測されるが、等値判定ができない。
0 と等しいかどうかという判定のためには (Eq a) という型指定が必要。
Possible fix:
add (Eq n) to the context of
the type signature for:
finiteRandoms :: forall g a n.
(RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
可能な修正:次の型シグネチャに(eq n)を追加するといいよ。
修正した
Haskellコンパイラからのアドバイスにより、次のようにしたら、無事コンパイルできた。
finiteRandoms :: (RandomGen g, Random a, Num n, Eq n) => n -> g -> ([a], g)
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)
Haskellのエラーメッセージは、とてもていねい。
しっかり読まなくては。
参考
『すごいHaskell 楽しく学ぼう』
著者: Miran Lipovaća
訳者: 田中英行・村主崇行
発行: オーム社
平成25年5月30日 第1版第6刷
カテゴリー: Haskell, memo
タグ: Eq, error, Haskell, Num
カウント: 30