I've started experimenting with Haskell and have a problem. qqq is a function that should print one string if called with "Nothing" and print other things if called with "Just something".
The first attempt seems like working:
qqq Nothing = print "There isn't anything to be printed."
qqq (Just x) = print "There is something to be printed." >> print x
main :: IO ()
main = qqq (Just 43)
But:
- when I try to make
main = qqq (Nothing)
it fails ("Ambiguous type variable `a0' in the constraint: (Show a0) arising from a use of 'qqq'") - When I want to add type signature if fails:
qqq :: Maybe x => x -> IO ()
->Type constructor 'Maybe' used as a class
-> But isn't it?
qqq :: (Maybe x) -> IO ()
. Now the signature itself looks like succeed. Butmain = qqq (Just 43)
starts failing with that mysterious(Show a0)
error like inmain = qqq (Nothing)
case.
Questions:
- Why calling qqq with
Nothing
is so different than calling withJust 43
? - What is
(Show a0)
? It is mentioned only in error messages. Any attempts to use it lead to something like "Show not in the scope". - What is correct type signature for this? How to make Haskell print type signature it deduced? Expecting something like:
f 0 = 2
f x = (f (x-1)) + 3
main = print get_type_as_string(f)
-- prints "Number -> Number"
The type of
qqq
is:That means that
qqq
takes one parameter of typeMaybe a
and returns an IO action without a value, with the constraint thata
implements theShow
typeclass. To find out whatShow
is, you can use:i Show
in ghci.Show
is a typeclass which requires that a value of the type can be converted to a string.qqq
has the constraint becauseprint
wants to print out the value (print
has typeShow a => a -> IO ()
).Maybe
is not a typeclass but a data type. You can read more about typeclasses here.You can let GHC deduce the type signature either by typing the function in a .hs file, then loading the file with ghci (
ghci Myfile.hs
), and then typing:t qqq
for displaying the type. You can also define the function in the interactive session withlet qqq n = case n of { Nothing -> print "abc"; Just x -> print "def" >> print x }
(it looks a bit different because the function definition has to be on one line in ghci, but the meaning is the same).When main calls
qqq
withqqq (Just 43)
, it is clear the concrete type ofMaybe a
is a numeric type (ghci defaults to Integer), soqqq
has the concrete type ofMaybe Integer -> IO ()
. However, main callsqqq
withqqq Nothing
,a
could be anything (it is ambiguous) and ghci reports an error.