willow-0.1.0.0: src/Web/Willow/Common/Parser/Util.hs
{-|
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
]