1 -- The default type signature of type class methods are changed
2 -- to introduce a Liftable constraint and the same type class but on the 'Output' repr,
3 -- this setup avoids to define the method with boilerplate code when its default
4 -- definition with lift* and 'trans' does what is expected by an instance
5 -- of the type class. This is almost as explained in:
6 -- https://ro-che.info/articles/2016-02-03-finally-tagless-boilerplate
7 {-# LANGUAGE DefaultSignatures #-}
8 {-# LANGUAGE DeriveGeneric #-} -- For NFData instances
9 {-# LANGUAGE DeriveAnyClass #-} -- For NFData instances
10 {-# LANGUAGE DeriveLift #-} -- For TH.Lift (Exception tok)
11 {-# LANGUAGE PatternSynonyms #-} -- For Failure
12 {-# LANGUAGE StandaloneDeriving #-} -- For Show (Exception (InputToken inp))
13 {-# LANGUAGE InstanceSigs #-}
14 {-# LANGUAGE TemplateHaskell #-}
15 {-# LANGUAGE ViewPatterns #-} -- For unSomeFailure
16 -- | Semantic of the grammar combinators used to express parsers,
17 -- in the convenient tagless-final encoding.
18 module Symantic.Parser.Grammar.Combinators where
20 import Data.Proxy (Proxy(..))
21 import Control.Monad (Monad(..))
22 import Control.DeepSeq (NFData(..))
23 import GHC.Generics (Generic)
24 -- import Data.Set (Set)
25 -- import GHC.TypeLits (KnownSymbol)
26 import Data.Bool (Bool(..), not, (||))
27 import Data.Char (Char)
28 import Data.Either (Either(..))
29 import Data.Eq (Eq(..))
30 import Data.Ord (Ord(..))
31 import Data.Function ((.), flip, const)
33 import Data.Kind (Type, Constraint)
34 import Data.Maybe (Maybe(..))
36 import Data.String (String)
37 import Text.Show (Show(..))
38 import Type.Reflection (Typeable, typeRep, eqTypeRep, (:~~:)(..), SomeTypeRep(..))
39 import qualified Data.Functor as Functor
40 import qualified Data.List as List
41 import qualified Data.Set as Set
42 import qualified Language.Haskell.TH as TH
43 import qualified Language.Haskell.TH.Syntax as TH
45 import qualified Symantic.Univariant.Trans as Sym
46 import qualified Symantic.Univariant.Lang as H
47 import qualified Symantic.Univariant.Data as Prod
48 import qualified Symantic.Univariant.View
49 import Symantic.Parser.Grammar.Production
52 type ReprComb = Type -> Type
54 -- * Class 'CombAlternable'
55 class CombAlternable repr where
56 -- | @('alt' es l r)@ parses @(l)@ and return its return value or,
57 -- if it fails with an 'Exception' within @(es)@,
58 -- parses @(r)@ from where @(l)@ has left the input stream,
59 -- and returns its return value,
60 -- otherwise throw the 'Exception' again.
61 alt :: Exception -> repr a -> repr a -> repr a
62 throw :: ExceptionLabel -> repr a
63 -- | @('try' ra)@ records the input stream position,
64 -- then parses like @(ra)@ and either returns its value it it succeeds or fails
65 -- if it fails but with a reset of the input stream to the recorded position.
66 -- Generally used on the first alternative: @('try' rl '<|>' rr)@.
67 try :: repr a -> repr a
69 Sym.Liftable2 repr => CombAlternable (Sym.Output repr) =>
70 Exception -> repr a -> repr a -> repr a
72 Sym.Liftable repr => CombAlternable (Sym.Output repr) =>
73 ExceptionLabel -> repr a
75 Sym.Liftable1 repr => CombAlternable (Sym.Output repr) =>
78 throw = Sym.lift . throw
81 failure :: SomeFailure -> repr a
83 Sym.Liftable repr => CombAlternable (Sym.Output repr) =>
85 failure = Sym.lift . failure
87 -- | @(empty)@ parses nothing, always failing to return a value.
89 empty = failure (SomeFailure FailureEmpty)
91 data instance Failure CombAlternable
93 deriving (Eq, Ord, Show, TH.Lift, Generic, NFData)
95 -- ** Data family 'Failure'
96 -- | 'Failure's of the 'Grammar'.
97 -- This is an extensible data-type.
99 (comb :: ReprComb -> Constraint)
103 -- | Convenient utility to pattern-match a 'SomeFailure'.
104 pattern Failure :: Typeable comb => Failure comb -> SomeFailure
105 pattern Failure x <- (unSomeFailure -> Just x)
108 -- ** Type 'SomeFailure'
111 ({-Trans (Failure comb repr) repr,-}
113 , Show (Failure comb)
114 , TH.Lift (Failure comb)
115 , NFData (Failure comb)
118 SomeFailure (Failure comb {-repr a-})
119 instance Eq SomeFailure where
120 SomeFailure (_x::Failure x) == SomeFailure (_y::Failure y) =
121 case typeRep @x `eqTypeRep` typeRep @y of
124 instance Ord SomeFailure where
125 SomeFailure (_x::Failure x) `compare` SomeFailure (_y::Failure y) =
126 SomeTypeRep (typeRep @x) `compare`
127 SomeTypeRep (typeRep @y)
128 instance Show SomeFailure where
129 showsPrec p (SomeFailure x) = showsPrec p x
130 instance TH.Lift SomeFailure where
131 liftTyped (SomeFailure x) = [|| SomeFailure $$(TH.liftTyped x) ||]
132 instance NFData SomeFailure where
133 rnf (SomeFailure x) = rnf x
136 instance Trans (SomeFailure repr) repr where
137 trans (SomeFailure x) = trans x
140 -- | @(unSomeFailure c :: 'Maybe' ('Failure' comb repr a))@
141 -- extract the data-constructor from the given 'SomeFailure'
142 -- iif. it belongs to the @('Failure' comb repr a)@ data-instance.
143 unSomeFailure :: forall comb. Typeable comb => SomeFailure -> Maybe (Failure comb)
144 unSomeFailure (SomeFailure (c::Failure c)) =
145 case typeRep @comb `eqTypeRep` typeRep @c of
149 -- ** Type 'Exception'
151 = ExceptionLabel ExceptionLabel
153 deriving (Eq, Ord, Show, TH.Lift, Generic, NFData)
154 type ExceptionLabel = String
155 -- type Exceptions = Set Exception
157 -- | Like @('<|>')@ but with different returning types for the alternatives,
158 -- and a return value wrapped in an 'Either' accordingly.
159 (<+>) :: CombApplicable repr => CombAlternable repr => repr a -> repr b -> repr (Either a b)
160 p <+> q = H.left <$> p <|> H.right <$> q
162 (<|>) :: CombAlternable repr => repr a -> repr a -> repr a
163 (<|>) = alt ExceptionFailure
167 optionally :: CombApplicable repr => CombAlternable repr => repr a -> Production b -> repr b
168 optionally p x = p $> x <|> pure x
170 optional :: CombApplicable repr => CombAlternable repr => repr a -> repr ()
171 optional = flip optionally H.unit
173 option :: CombApplicable repr => CombAlternable repr => Production a -> repr a -> repr a
174 option x p = p <|> pure x
176 choice :: CombAlternable repr => [repr a] -> repr a
177 choice = List.foldr (<|>) empty
178 -- FIXME: Here hlint suggests to use Data.Foldable.asum,
179 -- but at this point there is no asum for our own (<|>)
181 maybeP :: CombApplicable repr => CombAlternable repr => repr a -> repr (Maybe a)
182 maybeP p = option H.nothing (H.just <$> p)
184 manyTill :: CombApplicable repr => CombAlternable repr => repr a -> repr b -> repr [a]
185 manyTill p end = let go = end $> H.nil <|> p <:> go in go
188 class CombProductionable repr where
189 infixl 4 <$>, <&>, <$, $>
190 data instance Failure CombProductionable
194 -- * Class 'CombApplicable'
195 -- | This is like the usual 'Functor' and 'Applicative' type classes
196 -- from the @base@ package, but using @('Production' a)@ instead of just @(a)@
197 -- to be able to use and pattern match on some usual terms of type @(a)@ (like 'H.id')
198 -- and thus apply some optimizations.
199 -- @(repr)@, for "representation", is the usual tagless-final abstraction
200 -- over the many semantics that this syntax (formed by the methods
201 -- of type class like this one) will be interpreted.
202 class CombApplicable repr where
203 -- | @(a2b '<$>' ra)@ parses like @(ra)@ but maps its returned value with @(a2b)@.
204 (<$>) :: Production (a -> b) -> repr a -> repr b
205 (<$>) f = (pure f <*>)
207 -- | Like '<$>' but with its arguments 'flip'-ped.
208 (<&>) :: repr a -> Production (a -> b) -> repr b
211 -- | @(a '<$' rb)@ parses like @(rb)@ but discards its returned value by replacing it with @(a)@.
212 (<$) :: Production a -> repr b -> repr a
215 -- | @(ra '$>' b)@ parses like @(ra)@ but discards its returned value by replacing it with @(b)@.
216 ($>) :: repr a -> Production b -> repr b
219 -- | @('pure' a)@ parses the empty string, always succeeding in returning @(a)@.
220 pure :: Production a -> repr a
222 Sym.Liftable repr => CombApplicable (Sym.Output repr) =>
223 Production a -> repr a
224 pure = Sym.lift . pure
226 -- | @(ra2b '<*>' ra)@ parses sequentially @(ra2b)@ and then @(ra)@,
227 -- and returns the application of the function returned by @(ra2b)@
228 -- to the value returned by @(ra)@.
229 (<*>) :: repr (a -> b) -> repr a -> repr b
231 Sym.Liftable2 repr => CombApplicable (Sym.Output repr) =>
232 repr (a -> b) -> repr a -> repr b
233 (<*>) = Sym.lift2 (<*>)
235 -- | @(ra '<*' rb)@ parses sequentially @(ra)@ and then @(rb)@,
236 -- and returns like @(ra)@, discarding the return value of @(rb)@.
237 (<*) :: repr a -> repr b -> repr a
238 (<*) = liftA2 H.const
240 -- | @(ra '*>' rb)@ parses sequentially @(ra)@ and then @(rb)@,
241 -- and returns like @(rb)@, discarding the return value of @(ra)@.
242 (*>) :: repr a -> repr b -> repr b
243 x *> y = (H.id <$ x) <*> y
245 -- | Like '<*>' but with its arguments 'flip'-ped.
246 (<**>) :: repr a -> repr (a -> b) -> repr b
247 (<**>) = liftA2 (H.flip H..@ (H.$))
249 (<**>) :: repr a -> repr (a -> b) -> repr b
250 (<**>) = liftA2 (\a f -> f a)
252 -- | @('liftA2' a2b2c ra rb)@ parses sequentially @(ra)@ and then @(rb)@,
253 -- and returns the application of @(a2b2c)@ to the values returned by those parsers.
254 liftA2 :: Production (a -> b -> c) -> repr a -> repr b -> repr c
255 liftA2 f x = (<*>) (f <$> x)
257 infixl 4 <*>, <*, *>, <**>
258 data instance Failure CombApplicable
262 (<:>) :: CombApplicable repr => repr a -> repr [a] -> repr [a]
263 (<:>) = liftA2 H.cons
265 sequence :: CombApplicable repr => [repr a] -> repr [a]
266 sequence = List.foldr (<:>) (pure H.nil)
268 traverse :: CombApplicable repr => (a -> repr b) -> [a] -> repr [b]
269 traverse f = sequence . List.map f
270 -- FIXME: Here hlint suggests to use Control.Monad.mapM,
271 -- but at this point there is no mapM for our own sequence
273 repeat :: CombApplicable repr => Int -> repr a -> repr [a]
274 repeat n p = traverse (const p) [1..n]
276 between :: CombApplicable repr => repr o -> repr c -> repr a -> repr a
277 between open close p = open *> p <* close
279 void :: CombApplicable repr => repr a -> repr ()
282 unit :: CombApplicable repr => repr ()
285 -- * Class 'CombFoldable'
286 class CombFoldable repr where
287 chainPre :: repr (a -> a) -> repr a -> repr a
288 chainPost :: repr a -> repr (a -> a) -> repr a
291 Sym.Liftable2 repr => CombFoldable (Sym.Output repr) =>
292 repr (a -> a) -> repr a -> repr a
294 Sym.Liftable2 repr => CombFoldable (Sym.Output repr) =>
295 repr a -> repr (a -> a) -> repr a
296 chainPre = Sym.lift2 chainPre
297 chainPost = Sym.lift2 chainPost
300 CombApplicable repr =>
301 CombAlternable repr =>
302 repr (a -> a) -> repr a -> repr a
304 CombApplicable repr =>
305 CombAlternable repr =>
306 repr a -> repr (a -> a) -> repr a
307 chainPre op p = go <*> p where go = (H..) <$> op <*> go <|> pure H.id
308 chainPost p op = p <**> go where go = (H..) <$> op <*> go <|> pure H.id
310 chainPre op p = flip (foldr ($)) <$> many op <*> p
311 chainPost p op = foldl' (flip ($)) <$> p <*> many op
313 data instance Failure CombFoldable
316 conditional :: CombSelectable repr => [(Production (a -> Bool), repr b)] -> repr a -> repr b -> repr b
317 conditional cs p def = match p fs qs def
318 where (fs, qs) = List.unzip cs
323 CombApplicable repr => CombFoldable repr =>
324 Production (a -> b -> b) -> Production b -> repr a -> repr b
325 pfoldr f k p = chainPre (f <$> p) (pure k)
328 CombApplicable repr => CombFoldable repr =>
329 Production (a -> b -> b) -> Production b -> repr a -> repr b
330 pfoldr1 f k p = f <$> p <*> pfoldr f k p
333 CombApplicable repr => CombFoldable repr =>
334 Production (b -> a -> b) -> Production b -> repr a -> repr b
335 pfoldl f k p = chainPost (pure k) ((H.flip <$> pure f) <*> p)
338 CombApplicable repr => CombFoldable repr =>
339 Production (b -> a -> b) -> Production b -> repr a -> repr b
340 pfoldl1 f k p = chainPost (f <$> pure k <*> p) ((H.flip <$> pure f) <*> p)
344 CombApplicable repr => CombFoldable repr =>
345 Production (a -> b) -> repr a -> repr (b -> a -> b) -> repr b
346 chainl1' f p op = chainPost (f <$> p) (H.flip <$> op <*> p)
349 CombApplicable repr => CombFoldable repr =>
350 repr a -> repr (a -> a -> a) -> repr a
351 chainl1 = chainl1' H.id
354 chainr1' :: ParserOps rep => rep (a -> b) -> repr a -> repr (a -> b -> b) -> repr b
355 chainr1' f p op = newRegister_ H.id $ \acc ->
356 let go = bind p $ \x ->
357 modify acc (H.flip (H..@) <$> (op <*> x)) *> go
361 chainr1 :: repr a -> repr (a -> a -> a) -> repr a
362 chainr1 = chainr1' H.id
364 chainr :: repr a -> repr (a -> a -> a) -> Production a -> repr a
365 chainr p op x = option x (chainr1 p op)
369 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
370 repr a -> repr (a -> a -> a) -> Production a -> repr a
371 chainl p op x = option x (chainl1 p op)
373 -- Derived Combinators
375 CombApplicable repr => CombFoldable repr =>
377 many = pfoldr H.cons H.nil
380 CombApplicable repr => CombFoldable repr =>
381 Int -> repr a -> repr [a]
382 manyN n p = List.foldr (const (p <:>)) (many p) [1..n]
385 CombApplicable repr => CombFoldable repr =>
390 CombApplicable repr => CombFoldable repr =>
392 --skipMany p = let skipManyp = p *> skipManyp <|> unit in skipManyp
393 skipMany = void . pfoldl H.const H.unit -- the void here will encourage the optimiser to recognise that the register is unused
396 CombApplicable repr => CombFoldable repr =>
397 Int -> repr a -> repr ()
398 skipManyN n p = List.foldr (const (p *>)) (skipMany p) [1..n]
401 CombApplicable repr => CombFoldable repr =>
403 skipSome = skipManyN 1
406 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
407 repr a -> repr b -> repr [a]
408 sepBy p sep = option H.nil (sepBy1 p sep)
411 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
412 repr a -> repr b -> repr [a]
413 sepBy1 p sep = p <:> many (sep *> p)
416 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
417 repr a -> repr b -> repr [a]
418 endBy p sep = many (p <* sep)
421 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
422 repr a -> repr b -> repr [a]
423 endBy1 p sep = some (p <* sep)
426 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
427 repr a -> repr b -> repr [a]
428 sepEndBy p sep = option H.nil (sepEndBy1 p sep)
431 CombApplicable repr => CombAlternable repr => CombFoldable repr =>
432 repr a -> repr b -> repr [a]
434 let seb1 = p <**> (sep *> (H.flip H..@ H.cons <$> option H.nil seb1)
435 <|> pure (H.flip H..@ H.cons H..@ H.nil))
439 sepEndBy1 :: repr a -> repr b -> repr [a]
440 sepEndBy1 p sep = newRegister_ H.id $ \acc ->
441 let go = modify acc ((H.flip (H..)) H..@ H.cons <$> p)
442 *> (sep *> (go <|> get acc) <|> get acc)
446 -- * Class 'CombMatchable'
447 class CombMatchable repr where
449 Eq a => repr a -> [Production (a -> Bool)] -> [repr b] -> repr b -> repr b
450 default conditional ::
451 Sym.Unliftable repr => Sym.Liftable1 repr => CombMatchable (Sym.Output repr) =>
452 Eq a => repr a -> [Production (a -> Bool)] -> [repr b] -> repr b -> repr b
453 conditional a ps bs = Sym.lift1 (conditional (Sym.unlift a) ps (Sym.unlift Functor.<$> bs))
455 match :: Eq a => repr a -> [Production a] -> (Production a -> repr b) -> repr b -> repr b
456 match a as a2b = conditional a ((H.equal H..@) Functor.<$> as) (a2b Functor.<$> as)
457 -- match a as a2b = conditional a (((H.eq H..@ H.qual) H..@) Functor.<$> as) (a2b Functor.<$> as)
458 data instance Failure CombMatchable
460 -- * Class 'CombSatisfiable'
461 class CombSatisfiable tok repr where
462 -- | Like 'satisfyOrFail' but with no custom failure.
463 satisfy :: Production (tok -> Bool) -> repr tok
464 satisfy = satisfyOrFail Set.empty
465 -- | Like 'satisfy' but with a custom set of 'SomeFailure's.
468 Production (tok -> Bool) -> repr tok
469 default satisfyOrFail ::
470 Sym.Liftable repr => CombSatisfiable tok (Sym.Output repr) =>
472 Production (tok -> Bool) -> repr tok
473 satisfyOrFail fs = Sym.lift . satisfyOrFail fs
475 data instance Failure (CombSatisfiable tok)
477 | FailureHorizon Int -- FIXME: use Natural?
478 | FailureLabel String
480 deriving (Eq, Show, Typeable, Generic, NFData)
481 -- | Global 'TH.Name' to refer to the @(InputToken inp)@ type
482 -- from TemplateHaskell code.
483 inputTokenProxy :: TH.Name
484 inputTokenProxy = TH.mkName "inputToken"
485 instance TH.Lift tok => TH.Lift (Failure (CombSatisfiable tok)) where
486 liftTyped :: forall m. TH.Quote m => Failure (CombSatisfiable tok) -> TH.Code m (Failure (CombSatisfiable tok))
489 $$(let inputToken :: TH.Code m (Proxy tok) =
490 TH.unsafeCodeCoerce (return (TH.VarE inputTokenProxy))
492 (Proxy :: Proxy tok') ->
494 FailureAny -> [|| FailureAny @tok' ||]
495 FailureHorizon h -> [|| FailureHorizon @tok' h ||]
496 FailureLabel lbl -> [|| FailureLabel @tok' lbl ||]
497 FailureToken tok -> [|| FailureToken $$(TH.liftTyped tok) ||]
502 CombApplicable repr =>
503 CombSatisfiable Char repr =>
505 char c = satisfyOrFail
506 (Set.singleton (SomeFailure (FailureToken c)))
507 ((H.equal H..@ H.char c))
510 item :: forall tok repr.
511 Eq tok => Show tok => Typeable tok => TH.Lift tok => NFData tok =>
512 CombSatisfiable tok repr => repr tok
514 (Set.singleton (SomeFailure (FailureAny @tok)))
515 (H.const H..@ H.bool True)
518 CombAlternable repr =>
519 CombSatisfiable Char repr =>
524 CombApplicable repr => CombAlternable repr =>
525 CombSatisfiable Char repr =>
526 [Char] -> repr [Char]
527 string = try . traverse char
530 Eq tok => Show tok => Typeable tok => TH.Lift tok => NFData tok =>
531 CombSatisfiable tok repr =>
533 oneOf ts = satisfyOrFail
534 (Set.fromList (SomeFailure . FailureToken Functor.<$> ts))
537 [||\t -> $$(ofChars ts [||t||])||])
540 TH.Lift tok => Eq tok =>
541 CombSatisfiable tok repr =>
543 noneOf cs = satisfy (production
544 (not . (`List.elem` cs))
545 [||\c -> not $$(ofChars cs [||c||])||])
548 TH.Lift tok => Eq tok =>
549 {-alternatives-}[tok] ->
550 {-input-}TH.CodeQ tok ->
552 ofChars = List.foldr (\tok acc ->
553 \inp -> [|| tok == $$inp || $$(acc inp) ||])
557 CombAlternable repr =>
558 CombApplicable repr =>
559 CombSatisfiable Char repr =>
560 CombLookable repr => repr ()
561 more = look (void (item @Char))
564 TH.Lift tok => Show tok => Eq tok => Typeable tok =>
565 CombAlternable repr =>
566 CombApplicable repr =>
567 CombSatisfiable tok repr =>
569 token tok = satisfy (H.equal H..@ H.constant tok) $> H.constant tok
570 -- token tok = satisfy [ExceptionToken tok] (H.eq H..@ H.qual H..@ H.char tok) $> H.char tok
573 TH.Lift tok => Eq tok => Show tok => Typeable tok =>
574 CombApplicable repr => CombAlternable repr =>
575 CombSatisfiable tok repr => [tok] -> repr [tok]
576 tokens = try . traverse token
578 -- * Class 'CombSelectable'
579 class CombSelectable repr where
580 branch :: repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c
582 Sym.Liftable3 repr => CombSelectable (Sym.Output repr) =>
583 repr (Either a b) -> repr (a -> c) -> repr (b -> c) -> repr c
584 branch = Sym.lift3 branch
585 data instance Failure CombSelectable
587 -- * Class 'CombLookable'
588 class CombLookable repr where
589 look :: repr a -> repr a
590 negLook :: repr a -> repr ()
591 default look :: Sym.Liftable1 repr => CombLookable (Sym.Output repr) => repr a -> repr a
592 default negLook :: Sym.Liftable1 repr => CombLookable (Sym.Output repr) => repr a -> repr ()
593 look = Sym.lift1 look
594 negLook = Sym.lift1 negLook
598 default eof :: Sym.Liftable repr => CombLookable (Sym.Output repr) => repr ()
599 -- eof = negLook (satisfy @Char (H.const H..@ H.bool True))
601 data instance Failure CombLookable
603 deriving (Eq, Show, Typeable, TH.Lift, Generic, NFData)
605 -- Composite Combinators
606 -- someTill :: repr a -> repr b -> repr [a]
607 -- someTill p end = negLook end *> (p <:> manyTill p end)
610 constp :: CombApplicable repr => repr a -> repr (b -> a)
611 constp = (H.const <$>)
616 (>>) :: CombApplicable repr => repr a -> repr b -> repr b
619 -- Monoidal Operations
622 (<~>) :: CombApplicable repr => repr a -> repr b -> repr (a, b)
623 (<~>) = liftA2 (H.runtime (,))
626 (<~) :: CombApplicable repr => repr a -> repr b -> repr a
630 (~>) :: CombApplicable repr => repr a -> repr b -> repr b
635 CombApplicable repr =>
636 Production (a -> b -> c) -> repr a -> repr b -> repr c
637 liftA2 f x = (<*>) (fmap f x)
640 CombApplicable repr =>
641 Production (a -> b -> c -> d) -> repr a -> repr b -> repr c -> repr d
642 liftA3 f a b c = liftA2 f a b <*> c
647 -- Combinators interpreters for 'Sym.Any'.
648 instance CombApplicable repr => CombApplicable (Sym.Any repr)
649 instance CombSatisfiable repr => CombSatisfiable (Sym.Any repr)
650 instance CombAlternable repr => CombAlternable (Sym.Any repr)
651 instance CombSelectable repr => CombSelectable (Sym.Any repr)
652 instance CombMatchable repr => CombMatchable (Sym.Any repr)
653 instance CombLookable repr => CombLookable (Sym.Any repr)
654 instance CombFoldable repr => CombFoldable (Sym.Any repr)