My開発メモ

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)
   |               ^

このエラーメッセージの意味が最初わからなかったのだが、次のページを見たら
内容がわかった。

型クラスNumEq ではない

エラーメッセージの意味

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のエラーメッセージは、とてもていねい。
しっかり読まなくては。

参考

型クラスNumEq ではない

『すごいHaskell 楽しく学ぼう』

著者: Miran Lipovaća
訳者: 田中英行・村主崇行
発行: オーム社
平成25年5月30日 第1版第6刷

カテゴリー: Haskell, memo

タグ: Eq, error, Haskell, Num

カウント: 30