Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

haskell - Works in ghci but not in the file

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...