i'm learning haskell , i've written function:
safehead :: [a] -> maybe safehead [] = nothing safehead (x:xs) = x
i'm trying test hspec:
import test.hspec main :: io () main = hspec spec spec :: spec spec = describe "safehead" $ "should return nothing empty list" $ safehead [] `shouldbe` nothing
but fails compile:
error:(14, 19) ghc: no instance (eq a0) arising use of ‘shouldbe’ type variable ‘a0’ ambiguous note: there several potential instances: instance eq => eq (maybe a) -- defined in ‘ghc.base’ instance eq => 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 second argument of ‘($)’, namely ‘safehead [] `shouldbe` nothing’ in second argument of ‘($)’, namely ‘it "should return nothing empty list" $ safehead [] `shouldbe` nothing’ in expression: describe "safehead" $ "should return nothing empty list" $ safehead [] `shouldbe` nothing
i have tried this:
safehead :: (eq a) => [a] -> maybe safehead [] = nothing safehead (x:xs) = x
but still fails with:
error:(14, 19) ghc: no instance (eq a0) arising use of ‘shouldbe’ type variable ‘a0’ ambiguous note: there several potential instances: instance (eq a, eq b) => eq (either 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 second argument of ‘($)’, namely ‘safehead [] `shouldbe` nothing’ in second argument of ‘($)’, namely ‘it "should return nothing empty list" $ safehead [] `shouldbe` nothing’ in expression: describe "safehead" $ "should return nothing empty list" $ safehead [] `shouldbe` nothing
i don't know what's problem here. if try other tests these, compiles fine:
"should return head" $ safehead [1] `shouldbe` 1 safehead [2,3,4,5,6,1] `shouldbe` 2
so, it's nothing
itself, cannot compared equals? how assert returns nothing
then? or function generic?
side note: i've seen similar error function:
palindrome :: (eq a) => [a] -> [a] palindrome xs = xs ++ reverse xs
when trying test empty lists:
palindrome [] `shouldbe` []
which fails with:
error:(26, 21) ghc: no instance (eq a0) arising use of ‘shouldbe’ type variable ‘a0’ ambiguous note: there several potential instances: instance eq => eq (maybe a) -- defined in ‘ghc.base’ instance eq => 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 stmt of 'do' block: palindrome [] `shouldbe` [] in second argument of ‘($)’, namely ‘do { palindrome [] `shouldbe` [] }’ in second argument of ‘($)’, namely ‘it "should turn list palindrome, reads same both forwards , backwards" $ { palindrome [] `shouldbe` [] }’
so, it's nothing itself, cannot compared equals?
what's nothing
's type? it's nothing :: maybe a
. , ghc doesn't a
in context: "the type variable ‘a0’ ambiguous". after all, shouldbe
takes can compared (==)
, shown. , maybe a
instance of eq
if a
instance of eq
. ghc can't possibly know which a
want use, need specify hand:
describe "safehead" $ "should return nothing empty list" $ safehead [] `shouldbe` (nothing :: maybe int)
that's not coercion, you're making clear which of possible types want use. other examples:
describe "safehead" $ "should return nothing empty list" $ safehead [] `shouldbe` (nothing :: maybe int) safehead [] `shouldbe` (nothing :: maybe ()) safehead [] `shouldbe` (nothing :: maybe integer) safehead [] `shouldbe` (nothing :: maybe char)
Comments
Post a Comment