2013-04-17 43 views
7

Neden aşağıdaki derleme yapar:Haskell - Belirsiz tip değişkeni, neden?

{-# 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']) 

Ama değişen mainthis için:

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 kesinlikle değil Num sınıftır içinde:

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

aşağıdaki hatayı verir o? Ve değilse, neden belirsizlik?

cevap

10

Sorun, isList ile değil, sabit 42 ile. Sabit 'a', somut bir Char türüne sahiptir. Sabit 42'nin beton tipi yoktur.

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

Derleyici somut bir tür gerektirir. Ana aşağıdaki değiştirirseniz, aşağıdaki gibi çalışır:

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

Ah, teşekkürler, bu mantıklı. Türünü bilmiyorsa derleyebilir. Ama neden "varsayılan" burada çalışmıyor? Tamsayı neden varsayılan değil? – Clinton

+0

Derleyici, Int olarak davranması gerektiğini belirten bir şey içermiyor. Aynı tanımlayıcı ... bir Int'e ihtiyaç duyan bir işleve geçtiyse, bu tür Int. Ama bu sizin için otomatik olarak varsayım yapmayacak. – mightybyte

+9

@Clinton: Varsayılan, yalnızca tüm kısıtlamaların standart sınıflara başvurması durumunda yapılır. 'IsList' standart bir sınıf değildir. Bu gereksinim, ExtendedDefaultRules' ile rahatlatılabilir. – hammar

İlgili konular