2013-07-08 17 views
8

GHC'de aşırı yüklenmenin ne kadar güçlü olduğunu araştırıyorum. Aşağıdaki kod yazdık:Haskell'de bu tür bir açıklama neden gereklidir?

class F_third_arg a where 
    run_f :: (Integer, a) -> Integer 

instance F_third_arg Integer where 
    run_f (_, x) = x 

instance F_third_arg String where 
    run_f (x, _) = x 

my_fun :: (F_third_arg a) => Integer -> (a -> Integer) 
my_fun x = \a -> run_f(x, a) 

main :: IO() 
main = putStrLn $ show(((my_fun::Integer->(Integer->Integer)) 5) $ 6) 

(evet, -XTypeSynonymInstances -XFlexibleInstances gerekir) ve derleyici my_fun çağrısına yakın tipi notunu ihtiyacı olduğunu şaşırdım. İki sayıya uygulanır - bu notun çıkarılmasıyla ilgili sorun nedir? Bu iki uzantı açıkken aşırı yükleme kuralları nelerdir?

+0

'FlexibleInstances' zaten" TypeSynonymInstances "anlamına gelir. putStrLn. show' 'print' ile eşdeğerdir. Ve çok fazla parensi atlatabilirsin ... – leftaroundabout

+3

** ** 'nin ** türü için gelince (elbette derleyici _infer_ türünü yapamaz: sayısal edebi polimorfiktir!), Bu konuda uzman değilim Ancak GHC genişletilmiş varsayılan kurallar işi yapar ('{- # LANGUAGE ExtendedDefaultRules # -}' veya GHCi). Daha iyi bir yol, print $ my_fun 5 (6 :: Integer) 'olacaktır. – leftaroundabout

+0

Teşekkürler! Yorumlarınız gerçekten faydalıdır. –

cevap

7

Kodunuzdaki sorun, sayı değişimlerinin kendilerinin zaten aşırı yüklenmiş olmasıdır. Yani, 6 değişkeni Num a => a, my_fun 5 ise F_third_arg b => b -> Integer tipindedir. Bu nedenle, tür çıkarımında, bu iki tip değişkeni birleştirir. onlar hakkında hiçbir diğer şartları vardır gibi, GHC burada kullanılacak somut türünü bulmak ve uygun bir hata mesajı verir olamaz:

 
test.hs:16:26: 
    No instance for (F_third_arg a0) arising from a use of `my_fun' 
    The type variable `a0' is ambiguous 
    Possible fix: add a type signature that fixes these type variable(s) 
    Note: there are several potential instances: 
     instance F_third_arg String -- Defined at test.hs:9:10 
     instance F_third_arg Integer -- Defined at test.hs:6:10 
    In the expression: (my_fun 5) 
    In the first argument of `show', namely `((my_fun 5) $ 6)' 
    In the second argument of `($)', namely `show ((my_fun 5) $ 6)' 

test.hs:16:38: 
    No instance for (Num a0) arising from the literal `6' 
    The type variable `a0' is ambiguous 
    Possible fix: add a type signature that fixes these type variable(s) 
    Note: there are several potential instances: 
     instance Num Double -- Defined in `GHC.Float' 
     instance Num Float -- Defined in `GHC.Float' 
     instance Integral a => Num (GHC.Real.Ratio a) 
     -- Defined in `GHC.Real' 
     ...plus three others 
    In the second argument of `($)', namely `6' 
    In the first argument of `show', namely `((my_fun 5) $ 6)' 
    In the second argument of `($)', namely `show ((my_fun 5) $ 6)' 

Bir derleyici Integer hem karşılamaktadır tek tip olduğunu fark düşünülebilir Gereksinimler, ancak bu tür sezgisel kodunuzu göreceli olarak kırılgan yapar, yani yeni bir örnek eklediğinizde kırılır (ör. F_third_arg Double). Bu nedenle derleyici kodu reddeder ve söz konusu tür hakkında açık olmanızı ister.

Düzeltmek için bir yol buldunuz, ancak soldaki alanın 6::Integer kullanım önerisi biraz daha iyi.