2013-04-17 13 views
7

はなぜ以下のコンパイルん:Haskell - あいまいな型変数、なぜですか?

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE OverlappingInstances #-} 

class IsList a where 
    isList :: a -> Bool 

instance IsList a where 
    isList x = False 

instance IsList [a] where 
    isList x = True 

main = print (isList 'a') >> print (isList ['a']) 

しかしthismainを変更:

main = print (isList 42) >> print (isList [42]) 

は、次のエラーを与える:

Ambiguous type variable `a0' in the constraints: 
    (Num a0) arising from the literal `42' at prog.hs:13:22-23 
    (IsList a0) arising from a use of `isList' at prog.hs:13:15-20 
Probable fix: add a type signature that fixes these type variable(s) 
In the first argument of `isList', namely `42' 
In the first argument of `print', namely `(isList 42)' 
In the first argument of `(>>)', namely `print (isList 42)' 

isListは確実Numクラスにされていませんそれ?そして、そうでなければ、あいまいさはなぜですか?

答えて

10

問題はisListではなく定数42です。定数 'a'は、具体的な型のCharを持ちます。定数42は具体的な型を持たない。

ghci> :t 42 
42 :: Num a => a 

コンパイラには具体的なタイプが必要です。メインを次のように変更すると動作します:

main = print (isList (42 :: Int)) >> print (isList [42 :: Int]) 
+0

ああ、感謝します。型を知らないとコンパイルできません。しかし、なぜ「不履行」はここで働かないのですか?なぜ整数にデフォルトしないのですか? – Clinton

+0

コンパイラは、それをIntとして処理する必要があることを示すものがありません。同じ識別子がIntを必要とする関数に渡された場合、その型はIntに統一されます。しかし、それは自動的にあなたのための仮定をするつもりはありません。 – mightybyte

+9

@Clinton:デフォルト設定は、すべての制約が標準クラスのみを参照する場合にのみ行われます。 'IsList'は標準クラスではありません。この要件は 'ExtendedDefaultRules'で緩和できます。 – hammar