I have a little ambiguous type variable problem. I love haskell but this is really what I still fail to handle. The problem is very easy and involves printf from Text.Printf. Since the problem is very general I'll just but in some sample code:
program = do
d <- addd 4 8
printf "%d" d
addd x y = return (x+y)
Of course printf is imported. The compiler then gives me an, obvious, ambiguous type variable error between Num and PrintfArg. I just don't know where to fit in the right type signature.
There are a few places you could put a type signature. Firstly, addd has most general type of (and the most general type is (almost always) what GHC infers when you leave off the signature):
addd :: (Monad m, Num a) => a -> a -> m a
You could restrict this to only work on a certain type by giving addd
an explicit type signature, so that it isn't at all polymorphic in the arguments, e.g.:
addd :: Monad m => Int -> Int -> m Int
-- or,
addd :: Monad m => Integer -> Integer -> m Integer
Or, you could inform GHC of the input type when you call addd
, e.g.:
d <- addd 4 (8 :: Integer)
and then the type inference will infer that 4
and d
are both Integer
s.
Lastly, you can give d
a type. Either when you use it (if you use d
multiple times, you only need a single annotation), like so:
printf "%d" (d :: Integer)
Or when you set it (requires the GHC extension ScopedTypeVariables
):
{-# LANGUAGE ScopedTypeVariables #-}
[...]
add = do
(d :: Integer) <- addd 4 8