如何解析用逗号代替小数点的浮点数?
How can I parse a float with a comma in place of the decimal point?
我想从一个文件中解析 Float
值,在该文件中使用逗号作为小数点分隔符来存储它们。因此我需要一个函数 myParse :: String -> Float
这样,例如 myParse "23,46" == 23.46
.
我对如何做到这一点有一些想法,但它们似乎都过于复杂,例如:
- 将字符串中的
,
替换为.
并使用read
;或
- 跟随this FP Complete blogpost (entitled Parsing Floats With Parsec),挑战单态限制的诅咒
是否有更简单的方法,或者我真的需要使用解析库?在第二种情况下,能否请您粘贴一些建议以帮助我入门?单态限制让我害怕,我相信必须有一种方法可以在不使用语言扩展的情况下做到这一点。
用 .
替换 ,
然后调用 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,单态限制不必担心,只要您拥有所有顶级绑定的类型签名。特别是,以下代码不需要任何语言扩展即可正确编译(至少在 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
我想从一个文件中解析 Float
值,在该文件中使用逗号作为小数点分隔符来存储它们。因此我需要一个函数 myParse :: String -> Float
这样,例如 myParse "23,46" == 23.46
.
我对如何做到这一点有一些想法,但它们似乎都过于复杂,例如:
- 将字符串中的
,
替换为.
并使用read
;或 - 跟随this FP Complete blogpost (entitled Parsing Floats With Parsec),挑战单态限制的诅咒
是否有更简单的方法,或者我真的需要使用解析库?在第二种情况下,能否请您粘贴一些建议以帮助我入门?单态限制让我害怕,我相信必须有一种方法可以在不使用语言扩展的情况下做到这一点。
用 .
替换 ,
然后调用 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,单态限制不必担心,只要您拥有所有顶级绑定的类型签名。特别是,以下代码不需要任何语言扩展即可正确编译(至少在 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