{-# LANGUAGE RankNTypes, ConstraintKinds, TypeFamilies, FlexibleContexts, ScopedTypeVariables, ViewPatterns #-} module Postdelay.TimeSpec.Utils where import Control.Applicative import Control.Monad import Control.Lens import Data.Time import Data.Time.Lens import Data.Time.Zones import Data.Functor import Data.AdditiveGroup import Text.Megaparsec import Text.Megaparsec.Prim (MonadParsec) import qualified Text.Megaparsec.Lexer as L type StringParser s m = (MonadParsec Dec s m, Token s ~ Char) spaceConsumer :: StringParser s m => m () spaceConsumer = L.space (void spaceChar) empty empty lexeme :: StringParser s m => m a -> m a lexeme = L.lexeme spaceConsumer signed, optSigned :: (StringParser s m, AdditiveGroup n) => m n -> m n signed = (<*>) (lexeme sign) optSigned = (<*>) (option id $ lexeme sign) sign :: (StringParser s m, AdditiveGroup n) => m (n -> n) sign = label "sign" $ choice [ char '+' $> id , char '-' $> negateV ] fromDigit :: Num n => Char -> n fromDigit c = fromIntegral $ fromEnum c - fromEnum '0'