2011-10-17 4 views
6

私はputStrLn $ showManyP "%d" 10 のようなファイルをロードした後GHCiの中で何かをしようとすると、それは動作しますが、これは動作しませんなぜ私は、ファイル main = putStrLn $ showManyP "%d" 10作品ではなく、ファイル内

でそれを書くときには、このエラーを与えます

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. 

実際のファイルはここから始まります:GHCで

{-# 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

、あなたは、01のような数値定数を入力すると、の場合は、Numのインスタンスであればどのタイプでもかまいません。追加の型制約がない場合、未定義のインスタンスであり、特定の型を指定する必要があります。すなわち(10 :: Int)。 Ghciはインタラクティブであり、数値を型に追加する必要があるので、タイプの制約がない場合、整数のようなものはIntegerの型であると仮定することで助けになります。これは、「2010年Haskellレポート」によると、GHCユーザーガイド2.4.5. Type defaulting in GHCi

に説明するが、4.3.4 Ambiguous Types, and Defaults for Overloaded Numeric Operationsに、あなたがコンパイルされたモジュールで、この動作を利用することができますdefaultキーワードがあります。

+3

これは完全に正しいわけではありません。 'default(Integer、Double)'の宣言に相当する、コンパイルされたHaskellモジュールでデフォルトの_is_を有効にします。しかし、 'Format'は標準クラスではないので、この場合は適用されません。 (あなたの最初のリンクを参照してください)。しかし、GHCiでは、この制限が解除されている。 – hammar

+0

上記の場合、Formatのデフォルト宣言を追加する方法を教えてください。 – Satvik

関連する問題