haskell - 更适合阅读 Haskell 中的科学记数法
问题描述
Haskellread
对浮点数有点过于严格:
$ ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Prelude> read "-1E34" :: Double
-1.0e34
Prelude> read "-1.E34" :: Double
*** Exception: Prelude.read: no parse
Prelude>
是否有接受第二种形式的 read 版本?这在物理科学中很常见。例如,Fortran 读取和写入此类表单。
Haskell 不支持的另一个例子是“0.1”的“.1”。这个更常见。我只是不想转换输入的 ascii 文件。. . .
解决方案
这是一个使用megaparsec执行此操作的自定义解析器。
import Text.Megaparsec
import Text.Megaparsec.Char
realLiteral :: (MonadParsec e s m, Token s ~ Char) => m Double
realLiteral = mkFloat <$> sign <*> intgPart <*> fracPart <*> exponent
where mkFloat sgn itg frc expn
= fromIntegral sgn * (fromIntegral itg + frc) * 10^^expn
sign = (-1) <$ char '-'
<|> 1 <$ char '+'
<|> pure 1
intgPart = read . ('0':) <$> many digitChar
fracPart = char '.' *> (toFrc<$>many digitChar)
<|> pure 0
where toFrc "" = 0
toFrc digits = read digits / 10^length digits
exponent = oneOf "eEdD" *> ((*) <$> sign <*> (read<$>some digitChar))
<|> pure 0
[1 of 1] 编译 Main(wtmpf-file5764.hs,解释) 好的,已加载 1 个模块。 *Main> parseMaybe realLiteral "1" 仅 1.0 *Main> parseMaybe realLiteral "-3" 只是(-3.0) *Main> parseMaybe realLiteral "-9e+2" 只是 (-900.0) *Main> parseMaybe realLiteral ".3e+9" 只需 3.0e8 *Main> parseMaybe realLiteral "-1.E34" 只是(-1.0000000000000001e34) *Main> parseMaybe realLiteral "-1.673986e-40" 只是(-1.6739859999999999e-40) *Main> parseMaybe realLiteral "-3.E+16" 只是(-3.0e16)
推荐阅读
- windows-subsystem-for-linux - WSL2 上的 Ubuntu 18.04:“登录失败:未授予用户在此计算机上请求的登录类型。”
- reactjs - 更改在滑块中显示给用户的值
- python - 在 Python 中过滤列表以仅包含来自 DynamoDB 扫描的电子邮件地址
- angular - Angular ngFor - 加载更多 - 加载相同项目时如何处理?
- python-3.x - Python 等效于 Perl 的 `$AUTOLOAD`
- java - 做了一个简单的计算器,但我需要添加一些东西
- gatsby - Algolia 将帖子链接到 0.0.7.227 网址
- linux - 如何找到在 Arch Linux 中运行的应用程序的进程名称
- c++ - 如何在类方法中运行线程?
- html - 如何在具有显示的元素中包含绝对元素:内容