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