2012-07-11 2 views
4

J'espérais que quelqu'un pourrait expliquer le comportement suivant dans GHCi, lorsque vous utilisez la fonction fromIntegral:comportement incompatible avec fromIntegral dans GHCi

Prelude> let x = 1 :: Integer                                      
Prelude> :t x                                          
x :: Integer                                          
Prelude> sqrt $ fromIntegral x                                     
1.0                                            
Prelude> let y = fromIntegral x                                     
Prelude> sqrt y                                         

<interactive>:181:1:                                        
No instance for (Floating Integer)                                   
    arising from a use of `sqrt'                                    
Possible fix: add an instance declaration for (Floating Integer)                            
In the expression: sqrt y                                      
In an equation for `it': it = sqrt y                                   

Pourquoi importe si je mets y puis prendre son sqrt ou tout simplement directement Prenez le sqrt?

+1

duplication possible de [Pourquoi 3 et x (qui a été affecté 3) ont différents types inférés dans Haskell?] (Http://stackoverflow.com/questions/7055146/why-do-3-and-x-which -was-assigned-3-have-différent-inferred-types-in-haskell) –

Répondre

9

fromIntegral est polymorphe dans son type de retour. Donc le type de y dans votre code pourrait être Num a => a. Ce type vous permettrait d'utiliser y comme argument à sqrt sans problème. Toutefois, en raison de la restriction du monomorphisme, le type de y n'est pas autorisé à être polymorphe. Par conséquent, il est défini par défaut sur le type Num par défaut, à savoir Integer.

Lorsque vous faites sqrt $ fromIntegral x la restriction de monomorphisme ne s'applique pas car elle s'applique uniquement aux variables globales et vous ne stockez pas le résultat de fromIntegral dans une variable cette fois.

Vous pouvez résoudre ce problème en ajoutant une signature de type à y (let y :: Num a => a; y = fromIntegal x) ou en désactivant la restriction de monomorphisme.

+4

Pour désactiver la restriction, ajoutez '{- # LANGUAGE NoMonomorphismRestriction # -}' en haut d'un fichier, ou entrez ': set - XNoMonomorphismRestriction' dans GHCi. –

+0

Il est généralement recommandé d'insérer ': set -XNoMonomorphismRestriction' dans votre fichier .ghci, car il s'agit principalement d'une erreur dans REPL. L'utiliser dans l'un de vos programmes est moins souvent nécessaire et pas toujours une bonne idée (puisqu'il peut interférer avec le partage). – Jedai