警告を回避する 次の制約をデフォルトで「Integer」型に設定する 質問する

警告を回避する 次の制約をデフォルトで「Integer」型に設定する 質問する

Int または文字列のリストを逆にする次の関数を定義しました。

myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = (myReverse xs) ++ [x]

hspec を使った私のテスト:

 describe "myReverse" $ do
  it "returns the inversed list of the given list" $ do
   myReverse [1,2,3,4] `shouldBe` [4,3,2,1]

  it "returns the inversed string of the given string" $ do
   myReverse "A man, a plan, a canal, panama!" `shouldBe` "!amanap ,lanac a ,nalp a ,nam A"

こうやって警告を受ける

tests/OneToTenSpec.hs:69:24:
    Warning: Defaulting the following constraint(s) to type `Integer'
               (Eq a0)
                 arising from a use of `shouldBe' at tests/OneToTenSpec.hs:69:24-33
               (Num a0)
                 arising from the literal `1' at tests/OneToTenSpec.hs:69:15
               (Show a0)
                 arising from a use of `shouldBe' at tests/OneToTenSpec.hs:69:24-33
    In a stmt of a 'do' block:
      myReverse [1, 2, 3, 4] `shouldBe` [4, 3, 2, 1]
    In the second argument of `($)', namely
      `do { myReverse [1, 2, ....] `shouldBe` [4, 3, ....] }'
    In a stmt of a 'do' block:
      it "returns the inversed list of the given list"
      $ do { myReverse [1, 2, ....] `shouldBe` [4, 3, ....] }

そこで私はテストに次の変更を加えました

myReverse [1 :: Int,2,3,4] `shouldBe` [4,3,2,1]

リストの要素の型を定義する以外に、この警告を回避する方法はありますか?

ベストアンサー1

数値リテラルではそうではありません。リテラルには 型がありNum a => a、それを で多態的な関数に渡しているのでa、何に解決するかについてのヒントはありませんa

良いニュースは、これがデフォルトが機能する仕組みであり、心配する必要がないということです。警告は迷惑ですが、回避する方法が2つあります。

  1. 明示的な型シグネチャを使用する
  2. 数値リテラルは使用しないでください

2はおそらくあなたのシナリオでは最適でしょう。要素の型がその機能に影響を与えないことが型からわかるので、自由に使用できます。Bool

 myReverse [True, False] `shouldBe` [False, True]

ちなみに、現在の実装は可能ですO(n^2)O(n)、その方法を見つけるのはあなたにお任せします :)

おすすめ記事