I am trying to write a Haskell function that returns the first item in the list.
h [] = Nothing
h (x:xs) = x
When I call it with an empty list:
main = print (h [])
I got the following error:
prog.hs:4:8:
No instance for (Show a0) arising from a use of `print'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
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 23 others
In the expression: print (h [])
In an equation for `main': main = print (h [])
I want the result to be Nothing when I give the function the empty list.
There are a few problems here, let's start by adding a reasonable type signature
h :: [a] -> Maybe a
h [] = Nothing
h (x:xs) = x
Now we get an error, we're returning a plain x so x needs to be of type Maybe a. We probably don't want this so we'll wrap it in the Just constructor
h (x:_) = Just x
Now on to your problem.
Notice that this isn't specific to your function, the result of
main = print $ head []
main = print $ id []
main = print $ tail []
are all the same.
The type of [] is [a]. Since we don't specify what a the type of h [] is Show a => Maybe a. The extra Show comes in because we want to print our result. But we don't actually say what a is so GHC freaks out being unable to default it.
There are two ways to fix it, the dumb way is to make h monomorphic (monomorphisize?) to h
h :: [Int] -> Maybe Int -- Bad
The smarter way is to simply choose a concrete type at our call site.
main = print $ h ([] :: [Int])
I chose Int for no particular reason, it doesn't matter that much. Now Maybe Int is printable so we're all set. The :: syntax works the same as it does for toplevel components, just declaring the type of [] in our expression is [Int].
Fun fact, GHCi has more aggressive defaulting than GHC. This means that
main = print []
is legal in GHCi but not in GHC. If you're getting a funny behavior, ask for the type of the expression to see what the default is
:t []
Compiler eat silent your function
h [] = Nothing
h (x:xs) = x
but h has a type [Maybe a] -> Maybe a , not [a] -> Maybe a.
h :: [a] -> Maybe a
h [] = Nothing
h (x:_) = Just x
[] is polymorphic type [a], so the function result h [], equals Nothig is still polymorphic type Maybe a, but print can't work with polymorphic type (if we haven't instance of Show). In gchi you can run
> print (h [])
but this case gchi will transform it into print ((h []) :: Maybe Int)
But if you have less polymorphic function, like:
h [] = Nothing
h (x:_) = Just $ x == ""
then compiler find it type h :: [String] -> Maybe Bool and print (h []) work!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With