packages feed

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
    ]