Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Works in ghci but not in the file

Tags:

haskell

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
like image 747
Satvik Avatar asked Oct 17 '11 20:10

Satvik


1 Answers

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.

like image 106
pat Avatar answered Sep 28 '22 10:09

pat