2011-10-17 23 views
6

當我嘗試在ghci的一些文件加載​​像putStrLn $ showManyP "%d" 10 它的工作原理,但之後爲什麼這不,當我把它寫在文件 main = putStrLn $ showManyP "%d" 10作品在ghci中而不是在文件

工作它給這個錯誤

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. 

實際的文件從這裏開始:

{-# 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 [email protected](x:xs) f | isPrefixOf f str = [[],drop (length f) str] 
        | otherwise = let (y:ys) = split xs f 
           in [x:y] ++ ys 

回答

9

在GHC,當你進入像01的數值不變,它可以是任何類型,它是Num的實例。如果沒有附加的類型約束,它是一個未定的實例,你必須提供一個特定的類型;即(10 :: Int)。 Ghci是交互式的,如果不得不爲數字添加類型將是一件痛苦的事情,所以它通過假設在沒有其他類型約束的情況下假設看起來像整數的東西是Integer類型。這是GHC用戶指南2.4.5. Type defaulting in GHCi

在解釋根據「2010哈斯克爾報告」,在4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operations,有一個default關鍵字,使您可以採取的這種行爲在編譯的模塊的優勢。

+3

這不完全正確。在已編譯的Haskell模塊中啓用類型默認_is_,相當於聲明'default(Integer,Double)'。然而它不適用於這種情況,因爲'Format'不是標準類。 (請參閱您的第一個鏈接)。然而,GHCi解除了這一限制。 – hammar

+0

你能告訴如何在上面的情況下添加格式的默認聲明..? – Satvik

相關問題