Why is printf "%d\n" 3
ambiguous but not show 3
? Could the printf
module be rewritten to provide automatic disambiguation? Presumably something like show
must be done at the lower levels of printf
... or is there some crucial difference between printf
and show
that requires the disambiguation of numbers?
If printf
can be rewritten to automatically handle numbers without explicit disambiguation, then what is show
doing right? How does show
turn numbers into strings without the :: Int
disambiguation of printf
?
Here is the correct operation of show
(without any disambiguation) and also the correct operation of printf
(with the disambiguation):
$ cat printStrLnShow3
import Text.Printf
main = putStrLn (show 3)
$ runghc printStrLnShow3
3
$ cat printfWithInt3
import Text.Printf
main = printf "%d\n" (3 :: Int)
$ runghc printfWithInt3
3
Here is the ambiguous variable error when printf
does not disambiguate the number:
$ cat printfWithAmbiguous3
import Text.Printf
main = printf "%d\n" 3
$ runghc printfWithAmbiguous3
printfWithAmbiguous3:2:8:
No instance for (PrintfArg a0) arising from a use of `printf'
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 [safe] PrintfArg Char -- Defined in `Text.Printf'
instance [safe] PrintfArg Double -- Defined in `Text.Printf'
instance [safe] PrintfArg Float -- Defined in `Text.Printf'
...plus 12 others
In the expression: printf "%d" 3
In an equation for `main': main = printf "%d" 3
printfWithAmbiguous3:2:22:
No instance for (Num a0) arising from the literal `3'
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 Num Double -- Defined in `GHC.Float'
instance Num Float -- Defined in `GHC.Float'
instance Integral a => Num (GHC.Real.Ratio a)
-- Defined in `GHC.Real'
...plus 11 others
In the second argument of `printf', namely `3'
In the expression: printf "%d" 3
In an equation for `main': main = printf "%d" 3