Il seguente codice è destinato a produrre un doppio o un intero. s
è assunto come negate
o id
; n
l'intera parte; e f
la parte frazionaria o Nothing
per un numero intero.Perdita di polimorfismo dopo la corrispondenza del modello
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)
quando compilo questo ottengo:
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
Sembra pista in qualche modo il compilatore ha perso il fatto che s
è polimorfico. Cosa è successo qui e come lo risolvo?
Interessante! Avevo trovato ciò che non andava (voleva davvero un "o a a") come ritorno, ma non mi rendevo conto che c'era un modo per aggirarlo. –
@leftaroundabout: In realtà hai bisogno di _universally_ quantificato 's' e questo è ciò che fa la firma di rank 2. 'ExistentialQuantification' non fa nulla in questo esempio, l'estensione importante è solo' Rank2Types'. – Vitus
@Vitus: ah, giusto! Continuo a mischiarlo, ma questo ha molto più senso, pensandoci. Modificato. – leftaroundabout