Problem z kodem polega na tym, że liczba literałów jest już przeciążona. Tak więc literalny 6
ma typ Num a => a
, natomiast my_fun 5
ma typ F_third_arg b => b -> Integer
. Więc podczas wnioskowania o typ, ujednolica te dwie zmienne typu. Ale jak nie ma innych wymagań o nich, GHC nie może znaleźć konkretny typ używania tutaj i daje odpowiedni komunikat o błędzie:
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)'
Można by oczekiwać, że kompilator zauważa, że Integer
jest jedynym typem, który spełnia zarówno wymagania, ale taka heurystyka spowodowałaby, że twój kod byłby względnie delikatny, tj. zepsułby się tylko dlatego, że dodałeś nową instancję (np. F_third_arg Double
). Dlatego kompilator odrzuca kod i prosi użytkownika o jednoznaczne zdanie na temat danego typu.
Znalazłeś jeden sposób, aby to naprawić, ale sugestia @ leftroundabouts użycia 6::Integer
jest nieco ładniejsza.
"FlexibleInstances" już oznacza "TypeSynonymInstances". 'putStrLn. show' jest równoważne 'print'. I możesz pominąć całkiem sporo paren ... – leftaroundabout
Co do typu ** defaulting ** (oczywiście kompilator nie może _inferować typu: literały liczbowe są polimorficzne!), Nie jestem ekspertem w tym zakresie, ale rozszerzone reguły GHC wykonują zadanie ('{- # LANGUAGE ExtendedDefaultRules # -}' lub GHCi). Lepszym sposobem byłoby "print $ my_fun 5 (6 :: Integer)". – leftaroundabout
Dzięki! Twoje komentarze są naprawdę pomocne. –