Applicative parsing
Use the applicative type of Parser.
Operators include use (<$>), (<*>), (<$), (<*), (*>), (<|>), many, and so on.
import Control.Monad-- showimport Text.Parsecimport Control.Applicative hiding ((<|>))number = many1 digitplus = char '+' *> numberminus = (:) <$> char '-' <*> numberinteger = plus <|> minus <|> numberfloat = fmap rd $ (++) <$> integer <*> decimal where rd = read :: String -> Float decimal = option "" $ (:) <$> char '.' <*> number-- /showmain = forever $ do putStrLn "Enter a float: " input <- getLine parseTest float input
*Main> mainEnter a float: 2.32.3Enter a float: 11.0Enter a float: -1-1.0Enter a float: +6.986.98
- Plus = char ' + ' *> number
P1 *> P2 matches p1 and P2 in turn, but P1 is discarded, returning only P2.
- minus = (:) <$> char '-' <*> number
(:) <$> p1 <*> p2 match p1 and P2 in turn, and then bind the results of two matches.
Here P1 matches the result is the character, P2 matches the result is the string, therefore uses (:) To connect.
- float = Fmap Rd $ (+ +) <$> integer <*> decimal
(+ +) <$> p1 <*> p2 match p1 and P2 in turn, and then bind the results two times.
The results of the two matches here are all strings, so use (+ +) to connect.
- decimal = Option "" $ (:) <$> char '. ' <*> number
Option "" P tries to match p if unsuccessful, returns an empty string "".
Reference links
Parsing floats with parsec
Haskell Language Learning Note (parsec) (3)