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

La *_*lle 16 haskell

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

myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = (myReverse xs) ++ [x]
Run Code Online (Sandbox Code Playgroud)

我用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"
Run Code Online (Sandbox Code Playgroud)

像这样我得到了警告

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, ....] }
Run Code Online (Sandbox Code Playgroud)

所以我在测试中做了以下更改

myReverse [1 :: Int,2,3,4] `shouldBe` [4,3,2,1]
Run Code Online (Sandbox Code Playgroud)

除了定义列表元素的类型之外,还有另一种方法可以避免此警告吗?

Dan*_*zer 20

不是数字文字.由于文字具有类型,Num a => a并且我们将其提供给具有多态性的函数a,因此没有关于要解决的内容的提示a.

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

  1. 使用显式类型签名
  2. 不要使用数字文字

2可能是你的场景中最好的,我们从类型中知道元素的类型不能影响它的功能,所以你可以自由使用 Bool

 myReverse [True, False] `shouldBe` [False, True]
Run Code Online (Sandbox Code Playgroud)

顺便说一句你目前的实现是O(n^2)O(n)是可能的,我将让你来,虽然弄清楚如何:)

  • 是`myReverse (x:xs) = last xs : myReverse (tail (x:xs))`吗? (2认同)