bling5630
bling5630

Reputation: 361

No instance for (Show b0) arising from a use of `print' The type variable `b0' is ambiguous

I'm trying to go through the Applicative example from Learn You a Haskell for Great Good! book.

my code is here:

class (Functor f) => Applicative f where  
    pure :: a -> f a  
    (<*>) :: f (a -> b) -> f a -> f b

instance Applicative Maybe where  
    pure = Just  
    Nothing <*> _ = Nothing  
    (Just f) <*> something = fmap f something  

main = do 
    print $ Just (+3) <*> Just 9 
    print $ pure (+3) <*> Just 10
    print $ pure (+3) <*> Just 9 
    print $ Just (++"hahah") <*> Nothing  
    print $ Nothing <*> Just "woot"

and I got this error message:

No instance for (Show b0) arising from a use of `print'
The type variable `b0' 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
In a stmt of a 'do' block: print $ Nothing <*> Just "woot"
In the expression:
  do { print $ Just (+ 3) <*> Just 9;
       print $ pure (+ 3) <*> Just 10;
       print $ pure (+ 3) <*> Just 9;
       print $ Just (++ "hahah") <*> Nothing;
       .... }

Why does it fail and how can I fix this?

Upvotes: 0

Views: 277

Answers (1)

jakubdaniel
jakubdaniel

Reputation: 2223

The problem lies in the last print line. Basically, you are applying a function String -> b by using <*>. It just so happens that you use Nothing to wrap the function, so there is no function in the end. The result of the application is some Maybe b where b is arbitrary, but only those as that are instances of Show produce instances for Maybe a. But remember you have an arbitrary b, which need not be an instance of Show. The print however requires its argument to be an instance of Show. Since you cannot prove b to be instance of Show neither can you prove Maybe b to be an instance of Show, thus print does not apply to the value of type Maybe b.

To make it go away you must specify what exact type of function you meant to be contained. So that the result has some known type:

(Nothing :: Maybe (String -> Int)) <*> ...

or you could just provide the type for the whole expression that is passed as input of the print:

print (... :: Maybe Int)

Upvotes: 3

Related Questions