Der folgende Code nicht kompiliert:Haskell polymorphe Funktionsauswertung Fehler
foo :: Num a => (a -> a) -> Either Integer Double -> Either Integer Double
foo f x = case x of
Left i -> Left $ f i
Right d -> Right $ f
und gibt die folgenden Fehler:
Couldn't match type `Integer' with `Double'
Expected type: Either Integer Double
Actual type: Either Integer a
In the expression: Right $ f d
In a case alternative: Right d -> Right $ f d
Dies ist eine Follow-up-Frage zu this question, das Problem durch gelöst mit RankNTypes:
(forall a. Num a => a -> a)
Aber die Antwort hat nichts gesagt. Ich möchte wissen:
Was ist die Ursache dieses Fehlers? Das Eventual-Ergebnis wäre nur einer der Case-Zweig, f würde nicht auf zwei Typen gleichzeitig eingegeben werden, sollte der Typ
f
überprüft werden, solangef :: Num a => (a -> a)
, entweder Integer -> Integer oder Double -> Double sollte Arbeit, könnte jemand erläutern, warum dies einen Fehler verursacht?Gibt es eine andere Möglichkeit, den Fehler zu beheben? Warum würde RankNTypes den Fehler beheben? Dies trifft mich wie der Monomorphie-Restriktionsfehler, den ich neulich bekommen habe, aber die Aktivierung hilft mir nicht, das zu beheben, und die explizite Typ-Annotation funktioniert auch nicht.
Stellen Sie sich vor, es würde checkcheck. Kannst du 'foo (+ 1.5) (Left 5)' nennen? Wenn nicht, warum nicht? Wenn ja, wie wäre das Ergebnis? –
Abgesehen von den Typ-Problemen könnten Sie 'foo f = entweder (Links. F) (Rechts. F)' schreiben. –