在Haskell中,更多可容纳的读物以获取科学符号



haskell的read在浮点数上有点严格:

$ 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>

是否有接受第二种形式的读版?它在物理科学中很普遍。例如,fortran读写并写下了这些形式。

Haskell不支持的另一个示例是" 0.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]编译主(wtmpf-file5764.hs,解释(好的,加载了1个模块。*主> parsemaybe realiteral" 1"只有1.0*main> parsemaybe realiteral" -3"Just(-3.0(*main> parsemaybe realiteral" -9e 2"Just(-900.0(*main> parsemaybe realiteral" .3e 9"只有3.0E8*main> parsemaybe realiteral" -1.e34"Just(-1.00000000000001E34(*Main> Parsemaybe Realiteral" -1.673986E-40"Just(-1.673985999999999E-40(*main> parsemaybe realiteral" -3.e 16"Just(-3.0E16(

正如某人所说,您可以创建一个辅助功能(或三个(,以帮助将数字转换为与read一起使用的格式。我不是Haskell最好的,所以我不确定还有哪些其他解决方案,但是我写了一些功能来提供帮助。我已经用read进行了测试,到目前为止,一切似乎都很好。

prefixZero :: String -> String
prefixZero ""         = ""
prefixZero ('-' : xs) = '-' : '0' : xs
prefixZero s          = '0' : s
suffixZero :: String -> String
suffixZero ""                    = ""
suffixZero ('.' : exp@('E' : _)) = '.' : '0' : exp
suffixZero (x : xs)              = x : suffixZero xs
format :: String -> String
format = suffixZero . prefixZero

您可以调用以下内容:

read (format "-1.E34") :: Double

输出以下输出:

-1.0e34

相关内容

  • 没有找到相关文章

最新更新