Reputation: 11218
when I try something in ghci after loading the file like putStrLn $ showManyP "%d" 10
it works but why this don't work when I write it in the file
main = putStrLn $ showManyP "%d" 10
It gives this error
printf.hs:37:19:
Ambiguous type variable `a0' in the constraints:
(Format a0) arising from a use of `showManyP' at printf.hs:37:19-27
(Num a0) arising from the literal `10' at printf.hs:37:34-35
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely `showManyP "%d" 10'
In the expression: putStrLn $ showManyP "%d" 10
In an equation for `main': main = putStrLn $ showManyP "%d" 10
Failed, modules loaded: none.
The actual file begins here:
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
import Data.List (intercalate,isPrefixOf)
class Showable a where
showManyP :: String -> a
instance Showable String where
showManyP str = str
instance (Showable s,Format a) => Showable (a->s) where
showManyP str a = showManyP (format str a)
class Format a where
format :: String -> a -> String
instance Format String where
format str a = replace "%s" str a
instance Format Char where
format str a = replace "%c" str [a]
instance Num a=>Format a where
format str a = replace "%d" str (show a)
replace :: String -> String -> String -> String
replace f str value = intercalate value $ split str f
split :: String -> String -> [String]
split [] f = [[]]
split str [] = [str]
split str@(x:xs) f | isPrefixOf f str = [[],drop (length f) str]
| otherwise = let (y:ys) = split xs f
in [x:y] ++ ys
Upvotes: 6
Views: 315
Reputation: 12749
In ghc, When you enter a numeric constant like 10
, it can be any type that is an instance of Num
. If there are no additional type constraints, it is an undecided instance, and you must provide a specific type; i.e. (10 :: Int)
. Ghci is interactive, and it would be a pain to have to add types to numbers, so it helps you out by assuming that, in the absence of additional type constraints, that things that look like integers are of type Integer
. This is explained in the GHC User Guide 2.4.5. Type defaulting in GHCi
According to the "2010 Haskell Report", in 4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations, there is a default
keyword that allows you to take advantage of this behavior in compiled modules.
Upvotes: 9