{-| Description: Small helpers for constructing parsers. Copyright: (c) 2020-2021 Sam May License: MPL-2.0 Maintainer: ag.eitilt@gmail.com Stability: experimental Portability: portable -} module Web.Willow.Common.Parser.Util ( range , choice , findNext ) where import qualified Control.Applicative as A import Control.Applicative ( (<|>) ) import Web.Willow.Common.Parser -- | Test whether a given value falls within the range defined by the two -- bounds, inclusive. -- -- >>> range 1 2 3 -- False -- -- >>> range 1 3 2 -- True -- -- >>> range 1 2 2 -- True range :: Ord a => a -- ^ Low bound -> a -- ^ High bound -> a -- ^ Value to test -> Bool range low high test = test >= low && test <= high -- | Reduce a list of 'A.Alternative's, such that the first successful instance -- will be run. If the list is empty, the resulting value will always fail. choice :: A.Alternative m => [m a] -> m a choice = foldr (<|>) A.empty -- | Scan through the stream, until the given parser succeeds (discarding any -- tokens between the initial location and where the first success is found). -- Fails if the parser does not succeed at any point in the remainder of the -- stream. findNext :: MonadParser parser stream token => parser out -> parser out findNext target = choice [ target , next *> findNext target ]