2017-09-07 35 views
1

我有以下一段代码似乎与GHC编译后运行时一贯挂起(虽然没有与-Werror构建失败)。Haskell挂在号码转换

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 

,并试图访问myObj时,程序将被挂起。经过一番挖掘之后,似乎haskell在数字转换方面遇到困难(尽管上面的代码片段没有警告或错误)。如果我将上面的9更改为10,则它不会挂起。但我很好奇,为什么上面挂?

回答

5

10 % 9(理性)转换为科学是不会终止的。

10/9 :: Scientific 

From the documentation of Data.Scientific

警告:尽管科学是分数的情况下,方法 仅部分定义!当它们的输出具有无限的 十进制扩展时,具体地,收发和/或发散 (即循环并消耗所有空间)。当输入Rational 具有无限小数展开时,fromRational将发生偏差。考虑使用fromRationalRepetend 这些将检测重复的合理性并指示 开始的位置。

因此,试试这个来代替:

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

你必须决定什么样的措施是适当的。我决定在这里忽略Left的可能性。

+0

这是诚实的非常关心。在分子和分母来自用户输入的实际应用中,这种情况只会在一小部分请求中出现,这使得调试非常困难。看起来一般建议应该是不惜一切代价避免Data.Scientific,并且只在将数字转换为JSON时使用它。 – pretobomba