aboutsummaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Parsing/Future.hs
blob: 3379cc121a9a9f9249c6f7dbf35a0b5eaf8caa43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
   Module      : Text.Pandoc.Parsing.Future
   Copyright   : Copyright (C) 2006-2024 John MacFarlane
   License     : GPL-2.0-or-later
   Maintainer  : John MacFarlane <[email protected]>

Future type for parsing.
-}

module Text.Pandoc.Parsing.Future
  ( Future (..)
  , runF
  , askF
  , asksF
  , returnF
  )
where

import Prelude hiding (Applicative(..))
import Control.Applicative (Applicative(..))
import Control.Monad.Reader
  ( asks, runReader, MonadReader(ask), Reader, ReaderT(ReaderT) )

-- | Reader monad wrapping the parser state. This is used to possibly
-- delay evaluation until all relevant information has been parsed and
-- made available in the parser state.
newtype Future s a = Future { runDelayed :: Reader s a }
  deriving (Monad, Applicative, Functor)

instance Semigroup a => Semigroup (Future s a) where
  (<>) = liftA2 (<>)

instance (Semigroup a, Monoid a) => Monoid (Future s a) where
  mempty = return mempty
  mappend = (<>)

-- | Run a delayed action with the given state.
runF :: Future s a -> s -> a
runF = runReader . runDelayed

askF :: Future s s
askF = Future ask

asksF :: (s -> a) -> Future s a
asksF f = Future $ asks f

returnF :: Monad m => a -> m (Future s a)
returnF = return . return