3 ms·
parseAddress = let hexStr2Int = Prelude.read . ("0x" ++) in do start <- many1 hexDigit char '-' end <- many
by dan00 14y ago
parseAddress =
let hexStr2Int = Prelude.read . ("0x" ++)
in do start <- many1 hexDigit
char '-'
end <- many1 hexDigit
return $ Address (hexStr2Int start) (hexStr2Int end)
Or in applicative style (using attoparsec), which I like a lot more than the monadic style,
because you can read it quite literally from the left to the right:
parseAddress = Address <$> hexDigits <*> (dash *> hexDigits)
where
hexDigits = string "0x" *> takeWhile1 hexadecimal
dash = char '-'
- drostie 14y agoIt's not bad, but the "0x" is part of the conversion into an integer, not part of the parsed address. That is, the more-complicated-looking combinator converts the string "03-c0" to `Address 3 192`, while it looks like yours converts the string "0x03-0xc0" to to `Address "0x03" "0xc0"`. (I'm not totally sure about that; I'm still very new to Haskell. Thanks for the heads-up on attoparsec though.)
- tmhedberg 14y agoThe (* >) operator [1] (the space in the middle is just to circumvent HN's rather dumb comment formatting) sequences its two arguments, ignoring the one on the left. So string "0x" *> takeWhile1 hexadecimal parses a literal string "0x", then one or more hexadecimal digits, and the result is just the hexadecimal digits. [1] http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html#v:-42--62- http://hackage.haskell.org/packages/archive/base/latest/doc/...
- dan00 14y ago{-# LANGUAGE OverloadedStrings #-} import Control.Applicative import qualified Data.Attoparsec.Text as P import qualified Data.Text as T data Address = Address {start :: Int, end :: Int} deriving Show address = Address <$> hexDigits <*> (dash *> hexDigits) where hexDigits = P.string "0x" *> P.hexadecimal dash = P.char '-' parse parser str = P.feed (P.parse parser $ T.pack str) T.empty Put the above into a file like 'parse.hs'. ~> ghci parse.hs *Main> parse address "0x1-0x1" Done "" Address {start = 1, end = 1} You might need to install attoparsec beforehand: cabal install attoparsec
- evincarofautumn 14y agoBack to Parsec using applicative style, and parsing the same thing as the original. parseAddress = Address <$> hexDigits <*> (dash *> hexDigits) where hexDigits = read . ("0x" ++) <$> many1 hexDigit dash = char '-'