我正在学习Haskell,并且已经编写了以下函数:
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:xs) = Just x
我现在正在尝试使用HSpec对其进行测试:
import Test.Hspec
main :: IO ()
main = hspec spec
spec :: Spec
spec =
describe "safeHead" $
it "should return Nothing for empty list" $
safeHead [] `shouldBe` Nothing
但这无法编译:
Error:(14, 19) ghc: No instance for (Eq a0) arising from a use of ‘shouldBe’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Base’
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in ‘GHC.Real’
instance Eq Ordering -- Defined in ‘ghc-prim-0.4.0.0:GHC.Classes’
...plus 31 others
In the second argument of ‘($)’, namely
‘safeHead [] `shouldBe` Nothing’
In the second argument of ‘($)’, namely
‘it "should return Nothing for empty list"
$ safeHead [] `shouldBe` Nothing’
In the expression:
describe "safeHead"
$ it "should return Nothing for empty list"
$ safeHead [] `shouldBe` Nothing
我也尝试过这个:
safeHead :: (Eq a) => [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:xs) = Just x
但这仍然失败:
Error:(14, 19) ghc: No instance for (Eq a0) arising from a use of ‘shouldBe’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance (Eq a, Eq b) => Eq (Either a b)
-- Defined in ‘Data.Either’
instance Eq Data.Monoid.All -- Defined in ‘Data.Monoid’
instance forall (k :: BOX) (f :: k -> *) (a :: k).
Eq (f a) =>
Eq (Data.Monoid.Alt f a)
-- Defined in ‘Data.Monoid’
...plus 43 others
In the second argument of ‘($)’, namely
‘safeHead [] `shouldBe` Nothing’
In the second argument of ‘($)’, namely
‘it "should return Nothing for empty list"
$ safeHead [] `shouldBe` Nothing’
In the expression:
describe "safeHead"
$ it "should return Nothing for empty list"
$ safeHead [] `shouldBe` Nothing
我不知道这是什么问题。如果我尝试其他类似的测试,则可以正常编译:
it "should return the head" $ do
safeHead [1] `shouldBe` Just 1
safeHead [2,3,4,5,6,1] `shouldBe` Just 2
那么,这是关于Nothing
自身的事情,它不能被平等地比较吗?您如何断言那会返回Nothing
什么?还是我的功能太通用?
旁注:我已经看到与此功能类似的错误:
palindrome :: (Eq a) => [a] -> [a]
palindrome xs = xs ++ reverse xs
尝试测试空列表时:
palindrome [] `shouldBe` []
失败的原因是:
Error:(26, 21) ghc: No instance for (Eq a0) arising from a use of ‘shouldBe’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Eq a => Eq (Maybe a) -- Defined in ‘GHC.Base’
instance Eq a => Eq (GHC.Real.Ratio a) -- Defined in ‘GHC.Real’
instance Eq Ordering -- Defined in ‘ghc-prim-0.4.0.0:GHC.Classes’
...plus 32 others
In a stmt of a 'do' block: palindrome [] `shouldBe` []
In the second argument of ‘($)’, namely
‘do { palindrome [] `shouldBe` [] }’
In the second argument of ‘($)’, namely
‘it
"should turn a list into a palindrome, so it reads same both forwards and backwards"
$ do { palindrome [] `shouldBe` [] }’
所以,这与Nothing本身有关,无法通过均等进行比较吗?
什么是Nothing
?是Nothing :: Maybe a
。而GHCa
在这种情况下并不喜欢:“类型变量'a0'是不明确的”。毕竟,shouldBe
采取一切可以与之相比(==)
并显示出来的东西。和Maybe a
是Eq
ifa
的实例,是的实例Eq
。GHC可能不知道您要使用哪个 a
,因此您需要手动指定它:
describe "safeHead" $
it "should return Nothing for empty list" $
safeHead [] `shouldBe` (Nothing :: Maybe Int)
这不是强制性的,您只是在说明要使用的所有可能类型中的哪种。其他例子:
describe "safeHead" $
it "should return Nothing for empty list" $ do
safeHead [] `shouldBe` (Nothing :: Maybe Int)
safeHead [] `shouldBe` (Nothing :: Maybe ())
safeHead [] `shouldBe` (Nothing :: Maybe Integer)
safeHead [] `shouldBe` (Nothing :: Maybe Char)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句