module Turtle.Options.Parsers ( number , plus , minus , float , percent , Parser , (<:>) ) where import Control.Applicative (Applicative, (<$>), (<*>), (<*), (*>)) import Text.Parsec (Parsec, many1, digit, char, option, oneOf, (<|>)) type Parser a = Parsec String () a 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 -- | Shamelessly taken from http://stackoverflow.com/a/31358854/2287402 float :: Parser Float float = fmap rd $ integer <++> decimal <++> exponent where rd = read :: String -> Float decimal = option "" $ char '.' <:> number exponent = option "" $ oneOf "eE" <:> integer percent :: Parser Float percent = (/100) <$> float <* char '%'