2013-04-17 13 views
7

Dlaczego po kompilacji:Haskell - zmienna niejednoznaczna, dlaczego?

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

Ale zmieniając main do this:

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

daje następujący błąd:

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 pewno nie w klasie Num IS to? A jeśli nie, dlaczego dwuznaczność?

Odpowiedz

10

Problem nie jest związany z parametrem isList, ale ze stałą 42. Stała "a" ma konkretny typ Char. Stała 42 nie ma typu betonu.

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

Kompilator potrzebuje konkretnego rodzaju. To zadziała, jeśli zmienisz główne na:

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

Ah, dzięki, to ma sens. Może skompilować, jeśli nie zna swojego typu. Ale dlaczego tutaj nie działa "defaulting"? Dlaczego nie wybrać wartości domyślnej? – Clinton

+0

Kompilator nie ma niczego, co wskazywałoby, że powinien traktować to jako Int. Jeśli ten sam identyfikator był ... powiedzmy ... przekazany do funkcji, która potrzebował int, to typ ten byłby zunifikowany z Int. Ale nie zrobi to automatycznie dla ciebie. – mightybyte

+9

@ Clinton: Domyślnie jest wykonywane tylko wtedy, gdy wszystkie ograniczenia odnoszą się tylko do klas standardowych. 'IsList' nie jest klasą standardową. Wymóg ten można złagodzić za pomocą 'ExtendedDefaultRules'. – hammar

Powiązane problemy