2017-09-07 6 views
1

J'ai le morceau de code suivant qui semble se bloquer de façon constante lors de l'exécution avec après la compilation avec GHC (bien que pas de défaillances de construction avec -Werror).Haskell suspendu à la conversion de nombre

import Data.Aeson 
import Data.Scientific 
import qualified Data.HashMap.Strict as S 

myObj = Object $ 
    S.fromList [("bla", Number $ pc * 100.0)] 
    where pc = 10/9 

Et en essayant d'accéder à myObj le programme va se bloquer. Après quelques recherches, il semble que Haskell ait du mal avec la conversion du nombre (bien qu'il n'y ait pas d'avertissement ou d'erreur avec l'extrait ci-dessus). Si je change le 9 ci-dessus à un 10, il ne se bloque pas. Mais je suis curieux, pourquoi ce qui précède pend?

Répondre

5

La conversion de 10 % 9 (un Rational) en Scientifique est ce qui ne se termine pas.

10/9 :: Scientific 

From the documentation of Data.Scientific:

AVERTISSEMENT: Bien que la science est une instance de Fractional, les méthodes ne sont que partiellement définies! Spécifiquement recip et/vont diverger (c'est-à-dire en boucle et consommer tout l'espace) lorsque leurs sorties ont une expansion décimale infinie . fromRational va diverger lorsque l'entrée Rational a une expansion décimale infinie. Envisagez d'utiliser deRationalRepetend pour ces raisons qui détecteront la répétition et indiquer où il commence.

Par conséquent, essayez ceci:

let Right (x, _) = fromRationalRepetend Nothing (10/9) in x 

Vous devrez décider quelles mesures sont appropriées. J'ai décidé ici d'ignorer la possibilité de Left.

+0

Ceci est honnêtement extrêmement préoccupant. Dans une application du monde réel où le numérateur et le dénominateur proviennent de l'entrée de l'utilisateur, ce cas n'apparaît que dans une fraction des requêtes, ce qui rend extrêmement difficile le débogage. Il semble que le conseil général devrait être d'éviter Data.Scientific à tout prix et de ne l'utiliser que lors de la conversion de nombres en JSON. – pretobomba