避免警告默认以下约束来键入`Integer'

时间:2014-02-19 20:55:44

标签: haskell

我已经定义了以下函数来反转Int或string的列表:

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 个答案:

答案 0 :(得分:19)

不使用数字文字。由于文字的类型为Num a => a,我们将其提供给a中的多态函数,因此没有关于解决a的内容的提示。

好消息是,这正是默认的工作方式,你无需担心!警告很烦人,我可以想到两种避免它的方法

  1. 使用显式类型签名
  2. 不要使用数字文字
  3. 2可能是您的场景中最好的,我们从类型中知道元素的类型不会影响其功能,因此您可以自由使用Bool

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

    除此之外,您目前的实施方式是O(n^2)并且O(n)是可能的,我会留给您了解如何:)