base: Remove `Monad(fail)` method and reexport `MonadFail(fail)` instead
[ghc.git] / libraries / base / Text / ParserCombinators / ReadPrec.hs
1 {-# LANGUAGE Trustworthy #-}
2 {-# LANGUAGE NoImplicitPrelude #-}
3
4 -----------------------------------------------------------------------------
5 -- |
6 -- Module : Text.ParserCombinators.ReadPrec
7 -- Copyright : (c) The University of Glasgow 2002
8 -- License : BSD-style (see the file libraries/base/LICENSE)
9 --
10 -- Maintainer : libraries@haskell.org
11 -- Stability : provisional
12 -- Portability : non-portable (uses Text.ParserCombinators.ReadP)
13 --
14 -- This library defines parser combinators for precedence parsing.
15
16 -----------------------------------------------------------------------------
17
18 module Text.ParserCombinators.ReadPrec
19 (
20 ReadPrec,
21
22 -- * Precedences
23 Prec,
24 minPrec,
25
26 -- * Precedence operations
27 lift,
28 prec,
29 step,
30 reset,
31
32 -- * Other operations
33 -- | All are based directly on their similarly-named 'ReadP' counterparts.
34 get,
35 look,
36 (+++),
37 (<++),
38 pfail,
39 choice,
40
41 -- * Converters
42 readPrec_to_P,
43 readP_to_Prec,
44 readPrec_to_S,
45 readS_to_Prec,
46 )
47 where
48
49
50 import Text.ParserCombinators.ReadP
51 ( ReadP
52 , ReadS
53 , readP_to_S
54 , readS_to_P
55 )
56
57 import qualified Text.ParserCombinators.ReadP as ReadP
58 ( get
59 , look
60 , (+++), (<++)
61 , pfail
62 )
63
64 import GHC.Num( Num(..) )
65 import GHC.Base
66
67 import qualified Control.Monad.Fail as MonadFail
68
69 -- ---------------------------------------------------------------------------
70 -- The readPrec type
71
72 newtype ReadPrec a = P (Prec -> ReadP a)
73
74 -- Functor, Monad, MonadPlus
75
76 -- | @since 2.01
77 instance Functor ReadPrec where
78 fmap h (P f) = P (\n -> fmap h (f n))
79
80 -- | @since 4.6.0.0
81 instance Applicative ReadPrec where
82 pure x = P (\_ -> pure x)
83 (<*>) = ap
84 liftA2 = liftM2
85
86 -- | @since 2.01
87 instance Monad ReadPrec where
88 P f >>= k = P (\n -> do a <- f n; let P f' = k a in f' n)
89
90 -- | @since 4.9.0.0
91 instance MonadFail.MonadFail ReadPrec where
92 fail s = P (\_ -> MonadFail.fail s)
93
94 -- | @since 2.01
95 instance MonadPlus ReadPrec
96
97 -- | @since 4.6.0.0
98 instance Alternative ReadPrec where
99 empty = pfail
100 (<|>) = (+++)
101
102 -- precedences
103 type Prec = Int
104
105 minPrec :: Prec
106 minPrec = 0
107
108 -- ---------------------------------------------------------------------------
109 -- Operations over ReadPrec
110
111 lift :: ReadP a -> ReadPrec a
112 -- ^ Lift a precedence-insensitive 'ReadP' to a 'ReadPrec'.
113 lift m = P (\_ -> m)
114
115 step :: ReadPrec a -> ReadPrec a
116 -- ^ Increases the precedence context by one.
117 step (P f) = P (\n -> f (n+1))
118
119 reset :: ReadPrec a -> ReadPrec a
120 -- ^ Resets the precedence context to zero.
121 reset (P f) = P (\_ -> f minPrec)
122
123 prec :: Prec -> ReadPrec a -> ReadPrec a
124 -- ^ @(prec n p)@ checks whether the precedence context is
125 -- less than or equal to @n@, and
126 --
127 -- * if not, fails
128 --
129 -- * if so, parses @p@ in context @n@.
130 prec n (P f) = P (\c -> if c <= n then f n else ReadP.pfail)
131
132 -- ---------------------------------------------------------------------------
133 -- Derived operations
134
135 get :: ReadPrec Char
136 -- ^ Consumes and returns the next character.
137 -- Fails if there is no input left.
138 get = lift ReadP.get
139
140 look :: ReadPrec String
141 -- ^ Look-ahead: returns the part of the input that is left, without
142 -- consuming it.
143 look = lift ReadP.look
144
145 (+++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
146 -- ^ Symmetric choice.
147 P f1 +++ P f2 = P (\n -> f1 n ReadP.+++ f2 n)
148
149 (<++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
150 -- ^ Local, exclusive, left-biased choice: If left parser
151 -- locally produces any result at all, then right parser is
152 -- not used.
153 P f1 <++ P f2 = P (\n -> f1 n ReadP.<++ f2 n)
154
155 pfail :: ReadPrec a
156 -- ^ Always fails.
157 pfail = lift ReadP.pfail
158
159 choice :: [ReadPrec a] -> ReadPrec a
160 -- ^ Combines all parsers in the specified list.
161 choice ps = foldr (+++) pfail ps
162
163 -- ---------------------------------------------------------------------------
164 -- Converting between ReadPrec and Read
165
166 readPrec_to_P :: ReadPrec a -> (Int -> ReadP a)
167 readPrec_to_P (P f) = f
168
169 readP_to_Prec :: (Int -> ReadP a) -> ReadPrec a
170 readP_to_Prec f = P f
171
172 readPrec_to_S :: ReadPrec a -> (Int -> ReadS a)
173 readPrec_to_S (P f) n = readP_to_S (f n)
174
175 readS_to_Prec :: (Int -> ReadS a) -> ReadPrec a
176 readS_to_Prec f = P (\n -> readS_to_P (f n))
177