parsing - 如何用逗号代替小数点来解析 float ?

标签 parsing haskell parsec

我想从使用逗号作为小数分隔符存储的文件中解析Float值。因此,我需要一个函数 myParse::String -> Float ,例如 myParse "23,46"== 23.46

我对如何做到这一点有一些想法,但它们看起来都过于复杂,例如:

有没有更简单的方法,或者我真的需要使用解析库吗?对于第二种情况,您能否粘贴一些建议以便我开始?单态限制让我感到害怕,我相信必须有一种方法可以在不使用语言扩展的情况下做到这一点。

最佳答案

, 替换为 .,然后调用 read 就足够简单了;您只需要记住使用自己的专用函数而不是普通的旧read:

readFloatWithComma :: String -> Float
readFloatWithComma = read . sanitize
  where
    sanitize = map (\c -> if c == ',' then '.' else c)

在 GHCi 中:

λ> readFloatWithComma "23,46"
23.46
<小时/>

关于parsec方法,尽管the article you link to suggest ,只要您拥有所有顶级绑定(bind)的类型签名,就不必担心单态限制。特别是,以下代码不需要任何语言扩展即可正确编译(至少在 GHC 7.10.1 中):

import Text.Parsec
import Text.Parsec.String         ( Parser )
import Control.Applicative hiding ( (<|>) )

infixr 5 <++>
(<++>) :: Applicative f => f [a] -> f [a] -> f [a]
a <++> b = (++) <$> a <*> b

infixr 5 <:>
(<:>) :: Applicative f => f a -> f [a] -> f [a]
a <:>  b = (:) <$> a <*> b

number :: Parser String
number = many1 digit

plus :: Parser String
plus = char '+' *> number

minus :: Parser String
minus = char '-' <:> number

integer :: Parser String
integer = plus <|> minus <|> number

float :: Parser Float
float = fmap rd $ integer <++> decimal <++> exponent
    where rd       = read :: String -> Float
          decimal  = option "" $ ('.' <$ char ',') <:> number
          exponent = option "" $ oneOf "eE" <:> integer

在 GHCi 中:

λ> parseTest float "23,46"
23.46

关于parsing - 如何用逗号代替小数点来解析 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31358351/

相关文章:

Haskell 使用带有 Parsec 的累加器进行解析

java - 时间戳转换问题

java - 使用 OData v4 语法解析器

ruby - 我的 Treetop 语法有什么问题?

haskell - Haskell 是否有像 ActiveRecord 或 Sequel 这样的 SQL 查询组合库?

regex - 使用Haskell Parsec一次解析正则表达式

c - 解析已解析的字符串

haskell - 将 Data.Constraint.Forall 与等式约束一起使用

haskell - 为什么所有 Haskell 类型类都有法则?

haskell - "try"回溯了多远?