1

我是haskell的新手,我正在尝试同时学习hspec

module ExercisesSpec where

import Test.Hspec
import Test.QuickCheck
import Control.Exception (evaluate)


halve :: [a] -> ([a], [a])
halve xs = splitAt (length xs `div` 2) xs

main :: IO ()
main = hspec $ do
  describe "halve" $ do
    it "0 elements" $ do
      halve [] `shouldBe` ([],[])

    it "1 element" $ do
      halve [1] `shouldBe` ([],[1])

    it "2 elements" $ do
      halve [1,2] `shouldBe` ([1],[2])

    it "3 elements" $ do
      halve [1,2,3] `shouldBe` ([1],[2,3])

    it "4 elements" $ do
      halve [1,2,3,4] `shouldBe` ([1,2],[3,4])

尽管其余的测试都通过了,但对 0 元素的测试却失败了。

No instance for (Show a0) arising from a use of ‘shouldBe’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance Show Double -- Defined in ‘GHC.Float’
  instance Show Float -- Defined in ‘GHC.Float’
  instance (Integral a, Show a) => Show (GHC.Real.Ratio a)
    -- Defined in ‘GHC.Real’
  ...plus 38 others
In a stmt of a 'do' block: halve [] `shouldBe` ([], [])
In the second argument of ‘($)’, namely
  ‘do { halve [] `shouldBe` ([], []) }’
In a stmt of a 'do' block:
  it "0 elements" $ do { halve [] `shouldBe` ([], []) }

当我在 ghci 中尝试时,它工作正常。

*Exercises> halve []
([],[])

有人能帮我吗?

4

1 回答 1

5

啊,要回答我自己的问题,我发现我需要使类型更具体。如果我halve :: [Int] -> ([Int], [Int])在我的函数上方添加它,它会起作用。

引用我在班级讨论室读到的好答案:

pbl64k

一般来说,列表肯定没有可导出的 Show 实例。函数列表呢?REPL 推断出具有 Show 实例的具体类型。但是不要指望 [a] 通常会有一个——除非你自己做一个。

树鸮

pbl64k 有点对也有点错。如果存在 a 的 Show 实例,则存在 [a] 的 Show 实例。它是自动派生的。这里的问题是 Haskell 不知道它是哪个实例。[] 可能看起来像单个值(在机器代码中,它可能是),但在 Haskell 级别它是一个多态构造函数。它可以采用任何列表类型,因此您必须做一些事情来说明您想要的列表类型。

于 2014-11-16T05:01:55.360 回答