Der folgende Code soll entweder ein Double oder ein Integer erzeugen. s
wird entweder negate
oder id
angenommen; n
der ganze Teil; und f
der Bruchteil oder Nothing
für eine ganze Zahl.Verlust von Polymorphismus nach Mustererkennung
computeValue :: Num a => (a->a) -> Integer -> (Maybe Double) -> Either Double Integer
computeValue s n Nothing = Right $ s n
computeValue s n (Just a) = Left $ s (fromIntegral n + a)
, wenn ich das kompilieren bekomme ich:
test1.hs:2:28:
Couldn't match type `Integer' with `Double'
Expected type: Either Double Integer
Actual type: Either Double a
In the expression: Right $ s n
In an equation for `computeValue':
computeValue s n Nothing = Right $ s n
test1.hs:2:38:
Couldn't match type `Integer' with `Double'
In the first argument of `s', namely `n'
In the second argument of `($)', namely `s n'
In the expression: Right $ s n
Es scheint so, irgendwie der Compiler hat den Überblick verloren, die Tatsache, dass s
polymorph ist. Was ist hier passiert und wie repariere ich es?
Interessant! Ich hatte gefunden, was falsch war (es wollte wirklich ein "Entweder ein A") als eine Rückkehr, aber ich wusste nicht, dass es einen Weg gab. –
@leftaroundabout: Sie brauchen tatsächlich _universally_ quantifizierten 's' und das ist, was die Rang 2 Signatur tut. 'ExistentialQuantification' tut in diesem Beispiel nichts, die wichtige Erweiterung ist nur' Rank2Types'. – Vitus
@Vitus: Ach, richtig! Ich vermische es weiter, aber das macht viel mehr Sinn, darüber nachzudenken. Bearbeitet. – leftaroundabout