Das Problem mit Ihrem Code ist, dass Nummernliterale selbst bereits überlastet sind. So hat das Literal 6
den Typ Num a => a
, während my_fun 5
den Typ F_third_arg b => b -> Integer
hat. Während der Typinferenz werden also diese beiden Typvariablen vereinheitlicht. Aber da es keine anderen Anforderungen über sie sind, können GHC keine konkrete Art finden hier zu verwenden, und gibt eine entsprechende Fehlermeldung:
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)'
Man könnte erwarten, dass der Compiler merkt, dass Integer
die einzige Art ist, die beide erfüllt Anforderungen, aber solche Heuristiken würden Ihren Code relativ fragil machen, dh er würde brechen, nur weil Sie eine neue Instanz hinzufügen (zB F_third_arg Double
). Daher lehnt der Compiler den Code ab und bittet Sie, den fraglichen Typ explizit anzugeben.
Sie haben einen Weg gefunden, es zu beheben, aber @ leftroundabouts Vorschlag, 6::Integer
zu verwenden, ist ein bisschen netter.
'FlexibleInstances' bedeutet bereits' TypeSynonymInstances'. 'PutStrLn. show' entspricht "print". Und Sie können ziemlich viele Parens weglassen ... – leftaroundabout
Wie für den Typ ** defaulting ** (natürlich kann der Compiler nicht _infer_ der Typ: numerische Literale sind polymorph!), Ich bin kein Experte dafür, aber GHC erweiterte Standardregeln tun den Job ('{- # LANGUAGE ExtendedDefaultRules # -}' oder GHCi). Ein besserer Weg wäre 'print $ my_fun 5 (6 :: Integer)'. – leftaroundabout
Danke! Ihre Kommentare sind sehr hilfreich. –