packages feed

predicate-typed 0.7.2.0 → 0.7.3.0

raw patch · 38 files changed

+16410/−12825 lines, 38 filesdep +aeson-prettydep +string-conversionsPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: aeson-pretty, string-conversions

API changes (from Hackage documentation)

- Predicate.Core: instance forall a1 (p :: a1) a2. (GHC.Show.Show (Predicate.Core.PP p a2), Predicate.Core.P p a2, GHC.Show.Show a2) => Predicate.Core.P ('GHC.Maybe.Just p) (GHC.Maybe.Maybe a2)
- Predicate.Core: instance forall a1 b a2 (p :: b) x. (GHC.Show.Show a2, GHC.Show.Show (Predicate.Core.PP p a2), Predicate.Core.P p a2) => Predicate.Core.P ('Data.Either.Right p) (Data.Either.Either x a2)
- Predicate.Core: instance forall a1 b a2 (p :: b) x. (GHC.Show.Show a2, GHC.Show.Show (Predicate.Core.PP p a2), Predicate.Core.P p a2) => Predicate.Core.P ('Data.These.That p) (Data.These.These x a2)
- Predicate.Core: instance forall b a1 a2 (p :: a1) x. (GHC.Show.Show a2, GHC.Show.Show (Predicate.Core.PP p a2), Predicate.Core.P p a2) => Predicate.Core.P ('Data.Either.Left p) (Data.Either.Either a2 x)
- Predicate.Core: instance forall b a1 a2 (p :: a1) x. (GHC.Show.Show a2, GHC.Show.Show (Predicate.Core.PP p a2), Predicate.Core.P p a2) => Predicate.Core.P ('Data.These.This p) (Data.These.These a2 x)
- Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P '(p, q) a
- Predicate.Core: prtTree :: Show x => POpts -> TT x -> String
- Predicate.Prelude: class Bifunctor p => SwapC p
- Predicate.Prelude: data (q :: k) & (p :: k -> k1)
- Predicate.Prelude: data Abs p
- Predicate.Prelude: data All p q
- Predicate.Prelude: data AllNegative
- Predicate.Prelude: data AllPositive
- Predicate.Prelude: data AndA p q r
- Predicate.Prelude: data Ands p
- Predicate.Prelude: data Any p q
- Predicate.Prelude: data AppendFile (s :: Symbol) p
- Predicate.Prelude: data Asc
- Predicate.Prelude: data Asc'
- Predicate.Prelude: data Assoc
- Predicate.Prelude: data Between p q r
- Predicate.Prelude: data BetweenA p q
- Predicate.Prelude: data Bools (ps :: [(k, k1)])
- Predicate.Prelude: data BoolsN prt (n :: Nat) (p :: k1)
- Predicate.Prelude: data BoolsQuick (prt :: k) (ps :: [k1])
- Predicate.Prelude: data Both p q
- Predicate.Prelude: data Break p q
- Predicate.Prelude: data Case (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
- Predicate.Prelude: data Case' (ps :: [k]) (qs :: [k1]) (r :: k2)
- Predicate.Prelude: data Case'' s (ps :: [k]) (qs :: [k1]) (r :: k2)
- Predicate.Prelude: data CatMaybes q
- Predicate.Prelude: data Catch p q
- Predicate.Prelude: data Catch' p s
- Predicate.Prelude: data Ceiling (t :: Type) p
- Predicate.Prelude: data Ceiling' t p
- Predicate.Prelude: data Char1 (s :: Symbol)
- Predicate.Prelude: data ChunksOf n p
- Predicate.Prelude: data Cmp (o :: OrderingP) p q
- Predicate.Prelude: data CmpI (o :: OrderingP) p q
- Predicate.Prelude: data Coerce (t :: k)
- Predicate.Prelude: data Coerce2 (t :: k)
- Predicate.Prelude: data Concat p
- Predicate.Prelude: data ConcatMap p q
- Predicate.Prelude: data Cycle n p
- Predicate.Prelude: data Desc
- Predicate.Prelude: data Desc'
- Predicate.Prelude: data DirExists p
- Predicate.Prelude: data Div p q
- Predicate.Prelude: data DivMod p q
- Predicate.Prelude: data Do (ps :: [k])
- Predicate.Prelude: data DoN (n :: Nat) p
- Predicate.Prelude: data Dot (ps :: [Type -> Type]) (q :: Type)
- Predicate.Prelude: data Drop n p
- Predicate.Prelude: data Dup
- Predicate.Prelude: data Duplicate
- Predicate.Prelude: data EitherBool b p q
- Predicate.Prelude: data Elem p q
- Predicate.Prelude: data EmptyList (t :: Type)
- Predicate.Prelude: data EmptyList' t
- Predicate.Prelude: data EmptyT (t :: Type -> Type) p
- Predicate.Prelude: data EncodeJson p
- Predicate.Prelude: data EncodeJsonFile p q
- Predicate.Prelude: data EnumFromThenTo p q r
- Predicate.Prelude: data EnumFromTo p q
- Predicate.Prelude: data Even
- Predicate.Prelude: data ExitWhen prt p
- Predicate.Prelude: data Extract
- Predicate.Prelude: data FMapFst
- Predicate.Prelude: data FMapSnd
- Predicate.Prelude: data Fail t prt
- Predicate.Prelude: data FailS p
- Predicate.Prelude: data Failp p
- Predicate.Prelude: data Failt (t :: Type) p
- Predicate.Prelude: data FileExists p
- Predicate.Prelude: data Filter p q
- Predicate.Prelude: data First p
- Predicate.Prelude: data Floor (t :: Type) p
- Predicate.Prelude: data Floor' t p
- Predicate.Prelude: data FoldL p q r
- Predicate.Prelude: data FoldMap (t :: Type) p
- Predicate.Prelude: data FoldN n p q
- Predicate.Prelude: data FormatTimeP p q
- Predicate.Prelude: data FromEnum p
- Predicate.Prelude: data FromInteger (t :: Type) p
- Predicate.Prelude: data FromInteger' t n
- Predicate.Prelude: data FromIntegral (t :: Type) p
- Predicate.Prelude: data FromIntegral' t n
- Predicate.Prelude: data FromList (t :: Type)
- Predicate.Prelude: data FromListExt (t :: Type)
- Predicate.Prelude: data FromRational (t :: Type) p
- Predicate.Prelude: data FromRational' t r
- Predicate.Prelude: data FromString (t :: Type) p
- Predicate.Prelude: data FromString' t s
- Predicate.Prelude: data Fst p
- Predicate.Prelude: data GroupBy p q
- Predicate.Prelude: data Guard prt p
- Predicate.Prelude: data GuardSimple p
- Predicate.Prelude: data Guards (ps :: [(k, k1)])
- Predicate.Prelude: data GuardsDetail prt (ps :: [(k0, k1)])
- Predicate.Prelude: data GuardsN prt (n :: Nat) p
- Predicate.Prelude: data GuardsQuick (prt :: k) (ps :: [k1])
- Predicate.Prelude: data Head p
- Predicate.Prelude: data HeadDef p q
- Predicate.Prelude: data HeadFail msg q
- Predicate.Prelude: data Hole (t :: Type)
- Predicate.Prelude: data IToList (t :: Type) p
- Predicate.Prelude: data IToList' t p
- Predicate.Prelude: data IdBool p
- Predicate.Prelude: data If p q r
- Predicate.Prelude: data Init p
- Predicate.Prelude: data InitDef p q
- Predicate.Prelude: data InitFail msg q
- Predicate.Prelude: data Inits
- Predicate.Prelude: data Intercalate p q
- Predicate.Prelude: data IsControl
- Predicate.Prelude: data IsControlAll
- Predicate.Prelude: data IsDigit
- Predicate.Prelude: data IsDigitAll
- Predicate.Prelude: data IsEmpty
- Predicate.Prelude: data IsHexDigit
- Predicate.Prelude: data IsHexDigitAll
- Predicate.Prelude: data IsInfix p q
- Predicate.Prelude: data IsInfixI p q
- Predicate.Prelude: data IsJust p
- Predicate.Prelude: data IsLatin1
- Predicate.Prelude: data IsLatin1All
- Predicate.Prelude: data IsLeft p
- Predicate.Prelude: data IsLower
- Predicate.Prelude: data IsLowerAll
- Predicate.Prelude: data IsNothing p
- Predicate.Prelude: data IsOctDigit
- Predicate.Prelude: data IsOctDigitAll
- Predicate.Prelude: data IsPrefix p q
- Predicate.Prelude: data IsPrefixI p q
- Predicate.Prelude: data IsPunctuation
- Predicate.Prelude: data IsPunctuationAll
- Predicate.Prelude: data IsRight p
- Predicate.Prelude: data IsSeparator
- Predicate.Prelude: data IsSeparatorAll
- Predicate.Prelude: data IsSpace
- Predicate.Prelude: data IsSpaceAll
- Predicate.Prelude: data IsSuffix p q
- Predicate.Prelude: data IsSuffixI p q
- Predicate.Prelude: data IsThat p
- Predicate.Prelude: data IsThese p
- Predicate.Prelude: data IsThis p
- Predicate.Prelude: data IsUpper
- Predicate.Prelude: data IsUpperAll
- Predicate.Prelude: data IterateN n f
- Predicate.Prelude: data IterateNUntil n p f
- Predicate.Prelude: data IterateNWhile n p f
- Predicate.Prelude: data IterateUntil p f
- Predicate.Prelude: data IterateWhile p f
- Predicate.Prelude: data Ix (n :: Nat) def
- Predicate.Prelude: data Ix' (n :: Nat)
- Predicate.Prelude: data IxL p q def
- Predicate.Prelude: data Join
- Predicate.Prelude: data Just p
- Predicate.Prelude: data JustDef p q
- Predicate.Prelude: data JustFail p q
- Predicate.Prelude: data K (p :: k) (q :: k1)
- Predicate.Prelude: data Keep p q
- Predicate.Prelude: data L1 p
- Predicate.Prelude: data L2 p
- Predicate.Prelude: data L3 p
- Predicate.Prelude: data L4 p
- Predicate.Prelude: data L5 p
- Predicate.Prelude: data L6 p
- Predicate.Prelude: data Last p
- Predicate.Prelude: data LastDef p q
- Predicate.Prelude: data LastFail msg q
- Predicate.Prelude: data Left' p
- Predicate.Prelude: data LeftDef p q
- Predicate.Prelude: data LeftFail p q
- Predicate.Prelude: data Len
- Predicate.Prelude: data Length p
- Predicate.Prelude: data LogBase p q
- Predicate.Prelude: data Lookup p q
- Predicate.Prelude: data LookupDef v w p
- Predicate.Prelude: data LookupDef' v w p q
- Predicate.Prelude: data LookupFail msg v w
- Predicate.Prelude: data LookupFail' msg v w q
- Predicate.Prelude: data Luhn p
- Predicate.Prelude: data MConcat p
- Predicate.Prelude: data MEmpty2 (t :: Type)
- Predicate.Prelude: data MEmpty2' t
- Predicate.Prelude: data MEmptyP
- Predicate.Prelude: data MEmptyT (t :: Type)
- Predicate.Prelude: data MEmptyT' t
- Predicate.Prelude: data Map p q
- Predicate.Prelude: data MapMaybe p q
- Predicate.Prelude: data Max
- Predicate.Prelude: data MaybeBool b p
- Predicate.Prelude: data MaybeIn p q
- Predicate.Prelude: data Min
- Predicate.Prelude: data MkDay p
- Predicate.Prelude: data MkDay' p q r
- Predicate.Prelude: data MkDayExtra p
- Predicate.Prelude: data MkDayExtra' p q r
- Predicate.Prelude: data MkJust p
- Predicate.Prelude: data MkLeft (t :: Type) p
- Predicate.Prelude: data MkLeft' t p
- Predicate.Prelude: data MkNothing (t :: Type)
- Predicate.Prelude: data MkNothing' t
- Predicate.Prelude: data MkProxy
- Predicate.Prelude: data MkRight (t :: Type) p
- Predicate.Prelude: data MkRight' t p
- Predicate.Prelude: data MkThat (t :: Type) p
- Predicate.Prelude: data MkThat' t p
- Predicate.Prelude: data MkThese p q
- Predicate.Prelude: data MkThis (t :: Type) p
- Predicate.Prelude: data MkThis' t p
- Predicate.Prelude: data MkTime p
- Predicate.Prelude: data MkTime' p q r
- Predicate.Prelude: data Mod p q
- Predicate.Prelude: data Negate p
- Predicate.Prelude: data Not p
- Predicate.Prelude: data Null
- Predicate.Prelude: data Null' p
- Predicate.Prelude: data Odd
- Predicate.Prelude: data OneP p
- Predicate.Prelude: data Ones p
- Predicate.Prelude: data OrA p q r
- Predicate.Prelude: data OrdA p
- Predicate.Prelude: data OrdA' p q
- Predicate.Prelude: data Ors p
- Predicate.Prelude: data PadL n p q
- Predicate.Prelude: data PadR n p q
- Predicate.Prelude: data Pairs
- Predicate.Prelude: data Para (ps :: [k])
- Predicate.Prelude: data ParaN (n :: Nat) p
- Predicate.Prelude: data ParseJson (t :: Type) p
- Predicate.Prelude: data ParseJson' t p
- Predicate.Prelude: data ParseJsonFile (t :: Type) p
- Predicate.Prelude: data ParseJsonFile' t p
- Predicate.Prelude: data ParseTimeP (t :: Type) p q
- Predicate.Prelude: data ParseTimeP' t p q
- Predicate.Prelude: data ParseTimes (t :: Type) p q
- Predicate.Prelude: data ParseTimes' t p q
- Predicate.Prelude: data Partition p q
- Predicate.Prelude: data PartitionBy t p q
- Predicate.Prelude: data PartitionEithers
- Predicate.Prelude: data PartitionThese
- Predicate.Prelude: data PosixToUTCTime p
- Predicate.Prelude: data Pred p
- Predicate.Prelude: data PredB p q
- Predicate.Prelude: data PredB' q
- Predicate.Prelude: data Prime p
- Predicate.Prelude: data PrimeNext p
- Predicate.Prelude: data PrintF s p
- Predicate.Prelude: data PrintL (n :: Nat) s p
- Predicate.Prelude: data PrintT s p
- Predicate.Prelude: data Product
- Predicate.Prelude: data ProxyT (t :: Type)
- Predicate.Prelude: data ProxyT' t
- Predicate.Prelude: data Pure (t :: Type -> Type) p
- Predicate.Prelude: data Pure2 (t :: Type -> Type)
- Predicate.Prelude: data Quot p q
- Predicate.Prelude: data QuotRem p q
- Predicate.Prelude: data RDot (ps :: [Type -> Type]) (q :: Type)
- Predicate.Prelude: data Re p q
- Predicate.Prelude: data Re' (rs :: [ROpt]) p q
- Predicate.Prelude: data ReadBase (t :: Type) (n :: Nat) p
- Predicate.Prelude: data ReadBase' t (n :: Nat) p
- Predicate.Prelude: data ReadDir p
- Predicate.Prelude: data ReadEnv p
- Predicate.Prelude: data ReadEnvAll
- Predicate.Prelude: data ReadFile p
- Predicate.Prelude: data ReadMaybe (t :: Type) p
- Predicate.Prelude: data ReadMaybe' t p
- Predicate.Prelude: data ReadP (t :: Type) p
- Predicate.Prelude: data ReadP' t p
- Predicate.Prelude: data ReadQ (t :: Type) p
- Predicate.Prelude: data ReadQ' t p
- Predicate.Prelude: data Rem p q
- Predicate.Prelude: data Remove p q
- Predicate.Prelude: data Repeat (n :: Nat) p
- Predicate.Prelude: data ReplaceAll p q r
- Predicate.Prelude: data ReplaceAll' (rs :: [ROpt]) p q r
- Predicate.Prelude: data ReplaceAllString o p q r
- Predicate.Prelude: data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
- Predicate.Prelude: data ReplaceFn (o :: ReplaceFnSub) p
- Predicate.Prelude: data ReplaceFn1 p
- Predicate.Prelude: data ReplaceFn2 p
- Predicate.Prelude: data ReplaceFn3 p
- Predicate.Prelude: data ReplaceOne p q r
- Predicate.Prelude: data ReplaceOne' (rs :: [ROpt]) p q r
- Predicate.Prelude: data ReplaceOneString (o :: ReplaceFnSub) p q r
- Predicate.Prelude: data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
- Predicate.Prelude: data Rescan p q
- Predicate.Prelude: data Rescan' (rs :: [ROpt]) p q
- Predicate.Prelude: data RescanRanges p q
- Predicate.Prelude: data RescanRanges' (rs :: [ROpt]) p q
- Predicate.Prelude: data Resplit p q
- Predicate.Prelude: data Resplit' (rs :: [ROpt]) p q
- Predicate.Prelude: data Reverse
- Predicate.Prelude: data ReverseL
- Predicate.Prelude: data Right' p
- Predicate.Prelude: data RightDef p q
- Predicate.Prelude: data RightFail p q
- Predicate.Prelude: data Rotate n p
- Predicate.Prelude: data SConcat p
- Predicate.Prelude: data STimes n p
- Predicate.Prelude: data SapA
- Predicate.Prelude: data SapA' (t :: Type)
- Predicate.Prelude: data ScanN n p q
- Predicate.Prelude: data ScanNA q
- Predicate.Prelude: data Scanl p q r
- Predicate.Prelude: data Second q
- Predicate.Prelude: data Sequence
- Predicate.Prelude: data ShowBase (n :: Nat) p
- Predicate.Prelude: data ShowP p
- Predicate.Prelude: data Signum p
- Predicate.Prelude: data Singleton p
- Predicate.Prelude: data Skip p
- Predicate.Prelude: data Snd p
- Predicate.Prelude: data SortBy p q
- Predicate.Prelude: data SortOn p q
- Predicate.Prelude: data SortOnDesc p q
- Predicate.Prelude: data Span p q
- Predicate.Prelude: data SplitAt n p
- Predicate.Prelude: data SplitAts ns p
- Predicate.Prelude: data Stderr p
- Predicate.Prelude: data Stdin
- Predicate.Prelude: data Stdout p
- Predicate.Prelude: data StripL p q
- Predicate.Prelude: data StripR p q
- Predicate.Prelude: data Succ p
- Predicate.Prelude: data SuccB p q
- Predicate.Prelude: data SuccB' q
- Predicate.Prelude: data Sum
- Predicate.Prelude: data Swap
- Predicate.Prelude: data Tail p
- Predicate.Prelude: data TailDef p q
- Predicate.Prelude: data TailFail msg q
- Predicate.Prelude: data Tails
- Predicate.Prelude: data Take n p
- Predicate.Prelude: data That' p
- Predicate.Prelude: data ThatDef p q
- Predicate.Prelude: data ThatFail p q
- Predicate.Prelude: data Thats
- Predicate.Prelude: data Thd p
- Predicate.Prelude: data These' p
- Predicate.Prelude: data TheseDef p q
- Predicate.Prelude: data TheseFail p q
- Predicate.Prelude: data TheseId p q
- Predicate.Prelude: data TheseIn p q r
- Predicate.Prelude: data TheseX p q r s
- Predicate.Prelude: data Theses
- Predicate.Prelude: data This' p
- Predicate.Prelude: data ThisDef p q
- Predicate.Prelude: data ThisFail p q
- Predicate.Prelude: data Thiss
- Predicate.Prelude: data TimeUtc
- Predicate.Prelude: data TimeZt
- Predicate.Prelude: data ToDay p
- Predicate.Prelude: data ToEnum (t :: Type) p
- Predicate.Prelude: data ToEnum' t p
- Predicate.Prelude: data ToEnumBDef (t :: Type) def
- Predicate.Prelude: data ToEnumBDef' t def
- Predicate.Prelude: data ToEnumBFail (t :: Type)
- Predicate.Prelude: data ToList
- Predicate.Prelude: data ToList' p
- Predicate.Prelude: data ToListExt
- Predicate.Prelude: data ToLower
- Predicate.Prelude: data ToNEList
- Predicate.Prelude: data ToRational p
- Predicate.Prelude: data ToString p
- Predicate.Prelude: data ToTime p
- Predicate.Prelude: data ToTitle
- Predicate.Prelude: data ToUpper
- Predicate.Prelude: data ToWeekDate p
- Predicate.Prelude: data ToWeekYear p
- Predicate.Prelude: data Traverse p q
- Predicate.Prelude: data TrimBoth p
- Predicate.Prelude: data TrimL p
- Predicate.Prelude: data TrimR p
- Predicate.Prelude: data Truncate (t :: Type) p
- Predicate.Prelude: data Truncate' t p
- Predicate.Prelude: data UTCTimeToPosix p
- Predicate.Prelude: data UnMkDay p
- Predicate.Prelude: data UnMkTime p
- Predicate.Prelude: data Unassoc
- Predicate.Prelude: data Uncons
- Predicate.Prelude: data Uncurry (p :: Type -> Type -> Type -> Type) q r
- Predicate.Prelude: data Unfoldr p q
- Predicate.Prelude: data Unproxy
- Predicate.Prelude: data Unsnoc
- Predicate.Prelude: data Unwrap p
- Predicate.Prelude: data Unzip
- Predicate.Prelude: data Unzip3
- Predicate.Prelude: data Wrap (t :: Type) p
- Predicate.Prelude: data Wrap' t p
- Predicate.Prelude: data WriteFile (s :: Symbol) p
- Predicate.Prelude: data WriteFile' (s :: Symbol) p
- Predicate.Prelude: data Zip p q
- Predicate.Prelude: data ZipL l p q
- Predicate.Prelude: data ZipR r p q
- Predicate.Prelude: data ZipThese p q
- Predicate.Prelude: data p >|> q
- Predicate.Prelude: data q $& p
- Predicate.Prelude: infix 4 ...
- Predicate.Prelude: infixl 0 $$
- Predicate.Prelude: infixl 1 >>>
- Predicate.Prelude: infixl 3 <|>
- Predicate.Prelude: infixl 4 *>
- Predicate.Prelude: infixl 5 +:
- Predicate.Prelude: infixl 6 -
- Predicate.Prelude: infixl 7 /
- Predicate.Prelude: infixl 8 -%
- Predicate.Prelude: infixr 0 $
- Predicate.Prelude: infixr 1 >|>
- Predicate.Prelude: infixr 2 +++
- Predicate.Prelude: infixr 3 ***
- Predicate.Prelude: infixr 5 ++
- Predicate.Prelude: infixr 6 <>
- Predicate.Prelude: infixr 8 **
- Predicate.Prelude: instance (GHC.Classes.Ord a, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Max [a]
- Predicate.Prelude: instance (GHC.Classes.Ord a, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Min [a]
- Predicate.Prelude: instance (GHC.Num.Num a, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Product [a]
- Predicate.Prelude: instance (GHC.Num.Num a, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Sum [a]
- Predicate.Prelude: instance (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s)) => Predicate.Core.P Predicate.Prelude.Uncons s
- Predicate.Prelude: instance (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s)) => Predicate.Core.P Predicate.Prelude.Unsnoc s
- Predicate.Prelude: instance (GHC.Show.Show (f (t a)), GHC.Show.Show (f a), GHC.Base.Applicative t, GHC.Base.Functor f) => Predicate.Core.P (Predicate.Prelude.Pure2 t) (f a)
- Predicate.Prelude: instance (GHC.Show.Show (f (t a)), GHC.Show.Show (t (f a)), Data.Traversable.Traversable t, GHC.Base.Applicative f) => Predicate.Core.P Predicate.Prelude.Sequence (t (f a))
- Predicate.Prelude: instance (GHC.Show.Show (f a), GHC.Show.Show (f t), GHC.Types.Coercible t a, GHC.Base.Functor f) => Predicate.Core.P (Predicate.Prelude.Coerce2 t) (f a)
- Predicate.Prelude: instance (GHC.Show.Show (p (p a b) c), GHC.Show.Show (p a (p b c)), Predicate.Prelude.AssocC p) => Predicate.Core.P Predicate.Prelude.Assoc (p (p a b) c)
- Predicate.Prelude: instance (GHC.Show.Show (p (p a b) c), GHC.Show.Show (p a (p b c)), Predicate.Prelude.AssocC p) => Predicate.Core.P Predicate.Prelude.Unassoc (p a (p b c))
- Predicate.Prelude: instance (GHC.Show.Show (p a b), Predicate.Prelude.SwapC p, GHC.Show.Show (p b a)) => Predicate.Core.P Predicate.Prelude.Swap (p a b)
- Predicate.Prelude: instance (GHC.Show.Show (t (t a)), GHC.Show.Show (t a), GHC.Base.Monad t) => Predicate.Core.P Predicate.Prelude.Join (t (t a))
- Predicate.Prelude: instance (GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P Predicate.Prelude.ToList (t a)
- Predicate.Prelude: instance (GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P Predicate.Prelude.ToNEList (t a)
- Predicate.Prelude: instance (GHC.Show.Show (t a), GHC.Show.Show (t (t a)), Control.Comonad.Comonad t) => Predicate.Core.P Predicate.Prelude.Duplicate (t a)
- Predicate.Prelude: instance (GHC.Show.Show (t a), GHC.Show.Show a, Control.Comonad.Comonad t) => Predicate.Core.P Predicate.Prelude.Extract (t a)
- Predicate.Prelude: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Prelude.ToLower a
- Predicate.Prelude: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Prelude.ToTitle a
- Predicate.Prelude: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Prelude.ToUpper a
- Predicate.Prelude: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Prelude.PartitionEithers [Data.Either.Either a b]
- Predicate.Prelude: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Prelude.PartitionThese [Data.These.These a b]
- Predicate.Prelude: instance (GHC.Show.Show a, GHC.Show.Show t, GHC.Types.Coercible t a) => Predicate.Core.P (Predicate.Prelude.Coerce t) a
- Predicate.Prelude: instance (GHC.Show.Show a, as Data.Type.Equality.~ [a]) => Predicate.Core.P Predicate.Prelude.Len as
- Predicate.Prelude: instance (GHC.Show.Show a, as Data.Type.Equality.~ [a]) => Predicate.Core.P Predicate.Prelude.Reverse as
- Predicate.Prelude: instance (GHC.Show.Show as, Control.Lens.Empty.AsEmpty as) => Predicate.Core.P Predicate.Prelude.IsEmpty as
- Predicate.Prelude: instance (GHC.Show.Show l, GHC.Exts.IsList l, GHC.Show.Show (GHC.Exts.Item l)) => Predicate.Core.P Predicate.Prelude.ToListExt l
- Predicate.Prelude: instance (GHC.Show.Show l, GHC.Exts.IsList l, l Data.Type.Equality.~ l') => Predicate.Core.P (Predicate.Prelude.FromListExt l') l
- Predicate.Prelude: instance (GHC.Show.Show t, Control.Lens.Internal.Iso.Reversing t) => Predicate.Core.P Predicate.Prelude.ReverseL t
- Predicate.Prelude: instance (GHC.TypeLits.KnownSymbol s, GHC.TypeLits.CmpSymbol s "" Data.Type.Equality.~ 'GHC.Types.GT) => Predicate.Core.P (Predicate.Prelude.Char1 s) a
- Predicate.Prelude: instance (GHC.TypeNats.KnownNat n, GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Prelude.BoolsImpl n '[]) x
- Predicate.Prelude: instance (Predicate.Prelude.GetCharSet cs, GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P (Predicate.Prelude.IsCharSetAll cs) a
- Predicate.Prelude: instance (Predicate.Prelude.GetMode w, GHC.TypeLits.KnownSymbol s) => Predicate.Prelude.GetFHandle ('Predicate.Prelude.FOther s w)
- Predicate.Prelude: instance (Text.Printf.PrintfArg a, Predicate.Prelude.PrintC rs) => Predicate.Prelude.PrintC (a, rs)
- Predicate.Prelude: instance (TypeError ...) => Predicate.Core.P (Predicate.Prelude.ParaImpl n '[]) x
- Predicate.Prelude: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.GuardsImpl n '[]) x
- Predicate.Prelude: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.GuardsImplX n '[]) x
- Predicate.Prelude: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Inits x
- Predicate.Prelude: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P Predicate.Prelude.Tails x
- Predicate.Prelude: instance (a Data.Type.Equality.~ GHC.Exts.Item t, GHC.Show.Show t, GHC.Exts.IsList t, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Prelude.FromList t) x
- Predicate.Prelude: instance (x Data.Type.Equality.~ GHC.Types.Char, Predicate.Prelude.GetCharSet cs) => Predicate.Core.P (Predicate.Prelude.IsCharSet cs) x
- Predicate.Prelude: instance Data.Typeable.Internal.Typeable a => Predicate.Core.P Predicate.Prelude.Unproxy (Data.Proxy.Proxy a)
- Predicate.Prelude: instance Data.Typeable.Internal.Typeable t => Predicate.Core.P (Predicate.Prelude.Hole t) a
- Predicate.Prelude: instance GHC.Base.Functor f => Predicate.Core.P Predicate.Prelude.FMapFst (f (a, x))
- Predicate.Prelude: instance GHC.Base.Functor f => Predicate.Core.P Predicate.Prelude.FMapSnd (f (x, a))
- Predicate.Prelude: instance GHC.Classes.Eq Predicate.Prelude.BinOp
- Predicate.Prelude: instance GHC.Classes.Eq Predicate.Prelude.WFMode
- Predicate.Prelude: instance GHC.Show.Show Predicate.Prelude.BinOp
- Predicate.Prelude: instance GHC.Show.Show Predicate.Prelude.CharSet
- Predicate.Prelude: instance GHC.Show.Show Predicate.Prelude.WFMode
- Predicate.Prelude: instance GHC.Show.Show a => Predicate.Core.P Predicate.Prelude.MkProxy a
- Predicate.Prelude: instance GHC.Show.Show a => Predicate.Core.P Predicate.Prelude.Pairs [a]
- Predicate.Prelude: instance GHC.Show.Show s => GHC.Show.Show (Predicate.Prelude.FHandle s)
- Predicate.Prelude: instance GHC.Show.Show x => Predicate.Core.P Predicate.Prelude.Dup x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.DotExpandT ps q) a => Predicate.Core.P (Predicate.Prelude.Dot ps q) a
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.EmptyList t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.IxT' n) x => Predicate.Core.P (Predicate.Prelude.Ix' n) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.MEmpty2T t) x => Predicate.Core.P (Predicate.Prelude.MEmpty2 t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.MEmptyTT t) x => Predicate.Core.P (Predicate.Prelude.MEmptyT t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.MkNothing t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.ProxyT t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.RDotExpandT ps q) a => Predicate.Core.P (Predicate.Prelude.RDot ps q) a
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.SapAT' t) x => Predicate.Core.P (Predicate.Prelude.SapA' t) x
- Predicate.Prelude: instance Predicate.Core.P (Predicate.Prelude.ToEnumBFailT t) x => Predicate.Core.P (Predicate.Prelude.ToEnumBFail t) x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.AllNegativeT x => Predicate.Core.P Predicate.Prelude.AllNegative x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.AllPositiveT x => Predicate.Core.P Predicate.Prelude.AllPositive x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.AscT x => Predicate.Core.P Predicate.Prelude.Asc x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.AscT' x => Predicate.Core.P Predicate.Prelude.Asc' x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.DescT x => Predicate.Core.P Predicate.Prelude.Desc x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.DescT' x => Predicate.Core.P Predicate.Prelude.Desc' x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.EvenT x => Predicate.Core.P Predicate.Prelude.Even x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsControlAllT x => Predicate.Core.P Predicate.Prelude.IsControlAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsControlT x => Predicate.Core.P Predicate.Prelude.IsControl x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsDigitAllT x => Predicate.Core.P Predicate.Prelude.IsDigitAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsDigitT x => Predicate.Core.P Predicate.Prelude.IsDigit x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsHexDigitAllT x => Predicate.Core.P Predicate.Prelude.IsHexDigitAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsHexDigitT x => Predicate.Core.P Predicate.Prelude.IsHexDigit x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsLatin1AllT x => Predicate.Core.P Predicate.Prelude.IsLatin1All x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsLatin1T x => Predicate.Core.P Predicate.Prelude.IsLatin1 x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsLowerAllT x => Predicate.Core.P Predicate.Prelude.IsLowerAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsLowerT x => Predicate.Core.P Predicate.Prelude.IsLower x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsOctDigitAllT x => Predicate.Core.P Predicate.Prelude.IsOctDigitAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsOctDigitT x => Predicate.Core.P Predicate.Prelude.IsOctDigit x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsPunctuationAllT x => Predicate.Core.P Predicate.Prelude.IsPunctuationAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsPunctuationT x => Predicate.Core.P Predicate.Prelude.IsPunctuation x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsSeparatorAllT x => Predicate.Core.P Predicate.Prelude.IsSeparatorAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsSeparatorT x => Predicate.Core.P Predicate.Prelude.IsSeparator x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsSpaceAllT x => Predicate.Core.P Predicate.Prelude.IsSpaceAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsSpaceT x => Predicate.Core.P Predicate.Prelude.IsSpace x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsUpperAllT x => Predicate.Core.P Predicate.Prelude.IsUpperAll x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.IsUpperT x => Predicate.Core.P Predicate.Prelude.IsUpper x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.MEmptyPT x => Predicate.Core.P Predicate.Prelude.MEmptyP x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.NullT a => Predicate.Core.P Predicate.Prelude.Null a
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.OddT x => Predicate.Core.P Predicate.Prelude.Odd x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.ReadEnvAll a
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.SapAT x => Predicate.Core.P Predicate.Prelude.SapA x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.Stdin x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.ThatsT x => Predicate.Core.P Predicate.Prelude.Thats x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.ThesesT x => Predicate.Core.P Predicate.Prelude.Theses x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.ThissT x => Predicate.Core.P Predicate.Prelude.Thiss x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.TimeUtc a
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.TimeZt a
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.Unzip3T x => Predicate.Core.P Predicate.Prelude.Unzip3 x
- Predicate.Prelude: instance Predicate.Core.P Predicate.Prelude.UnzipT x => Predicate.Core.P Predicate.Prelude.Unzip x
- Predicate.Prelude: instance Predicate.Prelude.AssocC (,)
- Predicate.Prelude: instance Predicate.Prelude.AssocC Data.Either.Either
- Predicate.Prelude: instance Predicate.Prelude.AssocC Data.These.These
- Predicate.Prelude: instance Predicate.Prelude.ExtractL1C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL1C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL1C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL1C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL1C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL2C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL2C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL2C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL2C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL2C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL3C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL3C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL3C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL3C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL3C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL4C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL4C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL4C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL4C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL4C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL5C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL5C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL5C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL5C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL5C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL6C (a, b)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL6C (a, b, c)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL6C (a, b, c, d)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL6C (a, b, c, d, e)
- Predicate.Prelude: instance Predicate.Prelude.ExtractL6C (a, b, c, d, e, f)
- Predicate.Prelude: instance Predicate.Prelude.GetBinOp 'Predicate.Prelude.BAdd
- Predicate.Prelude: instance Predicate.Prelude.GetBinOp 'Predicate.Prelude.BMult
- Predicate.Prelude: instance Predicate.Prelude.GetBinOp 'Predicate.Prelude.BSub
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CControl
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CHexDigit
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CLatin1
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CLower
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CNumber
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.COctDigit
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CPunctuation
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CSeparator
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CSpace
- Predicate.Prelude: instance Predicate.Prelude.GetCharSet 'Predicate.Prelude.CUpper
- Predicate.Prelude: instance Predicate.Prelude.GetFHandle 'Predicate.Prelude.FStderr
- Predicate.Prelude: instance Predicate.Prelude.GetFHandle 'Predicate.Prelude.FStdout
- Predicate.Prelude: instance Predicate.Prelude.GetMode 'Predicate.Prelude.WFAppend
- Predicate.Prelude: instance Predicate.Prelude.GetMode 'Predicate.Prelude.WFWrite
- Predicate.Prelude: instance Predicate.Prelude.GetMode 'Predicate.Prelude.WFWriteForce
- Predicate.Prelude: instance Predicate.Prelude.PrintC ()
- Predicate.Prelude: instance Predicate.Prelude.SwapC (,)
- Predicate.Prelude: instance Predicate.Prelude.SwapC Data.Either.Either
- Predicate.Prelude: instance Predicate.Prelude.SwapC Data.These.These
- Predicate.Prelude: instance Predicate.Prelude.ToDayC Data.Time.Calendar.Days.Day
- Predicate.Prelude: instance Predicate.Prelude.ToDayC Data.Time.Clock.Internal.SystemTime.SystemTime
- Predicate.Prelude: instance Predicate.Prelude.ToDayC Data.Time.Clock.Internal.UTCTime.UTCTime
- Predicate.Prelude: instance Predicate.Prelude.ToDayC Data.Time.LocalTime.Internal.LocalTime.LocalTime
- Predicate.Prelude: instance Predicate.Prelude.ToDayC Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
- Predicate.Prelude: instance Predicate.Prelude.ToDayC GHC.Real.Rational
- Predicate.Prelude: instance Predicate.Prelude.ToStringC Data.ByteString.Internal.ByteString
- Predicate.Prelude: instance Predicate.Prelude.ToStringC Data.ByteString.Lazy.Internal.ByteString
- Predicate.Prelude: instance Predicate.Prelude.ToStringC Data.Text.Internal.Lazy.Text
- Predicate.Prelude: instance Predicate.Prelude.ToStringC Data.Text.Internal.Text
- Predicate.Prelude: instance Predicate.Prelude.ToStringC GHC.Base.String
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.Clock.Internal.DiffTime.DiffTime
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.Clock.Internal.SystemTime.SystemTime
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.Clock.Internal.UTCTime.UTCTime
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.LocalTime.Internal.LocalTime.LocalTime
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
- Predicate.Prelude: instance Predicate.Prelude.ToTimeC GHC.Real.Rational
- Predicate.Prelude: instance forall k (def :: k) a (n :: GHC.Types.Nat). (Predicate.Core.P def (Data.Proxy.Proxy a), Predicate.Core.PP def (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.TypeNats.KnownNat n, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.Ix n def) [a]
- Predicate.Prelude: instance forall k (f :: * -> *) a (t :: k). (GHC.Show.Show (f a), GHC.Show.Show (f (Predicate.Core.PP t (f a))), GHC.Base.Functor f, GHC.Base.Monoid (Predicate.Core.PP t (f a))) => Predicate.Core.P (Predicate.Prelude.MEmpty2' t) (f a)
- Predicate.Prelude: instance forall k (fh :: Predicate.Prelude.FHandle GHC.Types.Symbol) (p :: k) a. (Predicate.Prelude.GetFHandle fh, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Prelude.WriteFileImpl fh p) a
- Predicate.Prelude: instance forall k (l :: GHC.Types.Bool) (r :: GHC.Types.Bool) (p :: k) x. (Predicate.Util.FailUnlessT (Predicate.Util.OrT l r) ('GHC.TypeLits.Text "TrimImpl: left and right cannot both be False"), Predicate.Util.GetBool l, Predicate.Util.GetBool r, Data.Text.Lens.IsText (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.TrimImpl l r p) x
- Predicate.Prelude: instance forall k (n :: GHC.Types.Nat) (p :: k) a. Predicate.Core.P (Predicate.Prelude.DoNT n p) a => Predicate.Core.P (Predicate.Prelude.DoN n p) a
- Predicate.Prelude: instance forall k (n :: GHC.Types.Nat) (p :: k) a. Predicate.Core.P (Predicate.Util.RepeatT n p) a => Predicate.Core.P (Predicate.Prelude.Repeat n p) a
- Predicate.Prelude: instance forall k (n :: GHC.Types.Nat) (p :: k) x a. (Predicate.Core.P (Predicate.Prelude.ParaImpl (Predicate.Util.LenT (Predicate.Util.RepeatT n p)) (Predicate.Util.RepeatT n p)) x, Predicate.Util.GetLen (Predicate.Util.RepeatT n p), x Data.Type.Equality.~ [a]) => Predicate.Core.P (Predicate.Prelude.ParaN n p) x
- Predicate.Prelude: instance forall k (n :: GHC.Types.Nat) (ps :: [k]) (p :: k) a (p1 :: k). (GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.P (Predicate.Prelude.ParaImpl n (p1 : ps)) [a], Predicate.Core.PP (Predicate.Prelude.ParaImpl n (p1 : ps)) [a] Data.Type.Equality.~ [Predicate.Core.PP p a], GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.ParaImpl n (p : p1 : ps)) [a]
- Predicate.Prelude: instance forall k (p :: k) a (n :: GHC.Types.Nat). (GHC.Show.Show (Predicate.Core.PP p a), GHC.TypeNats.KnownNat n, GHC.Show.Show a, Predicate.Core.P p a) => Predicate.Core.P (Predicate.Prelude.ParaImpl n '[p]) [a]
- Predicate.Prelude: instance forall k (p :: k) a. (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a) => Predicate.Core.P (Predicate.Prelude.Skip p) a
- Predicate.Prelude: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Prelude.Length p) x
- Predicate.Prelude: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.ToList' p) x
- Predicate.Prelude: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.Ands p) x
- Predicate.Prelude: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.Ors p) x
- Predicate.Prelude: instance forall k (p :: k) x (t :: * -> *). (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (t (Predicate.Core.PP p x)), GHC.Base.Applicative t) => Predicate.Core.P (Predicate.Prelude.Pure t p) x
- Predicate.Prelude: instance forall k (p :: k) x a (n :: GHC.Types.Nat). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, 2 GHC.TypeNats.<= n, n GHC.TypeNats.<= 36, GHC.TypeNats.KnownNat n, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Prelude.ShowBase n p) x
- Predicate.Prelude: instance forall k (p :: k) x a (t :: * -> *). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show (t a), GHC.Show.Show a, GHC.Base.Alternative t) => Predicate.Core.P (Predicate.Prelude.EmptyT t p) x
- Predicate.Prelude: instance forall k (p :: k) x a b. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a b) => Predicate.Core.P (Predicate.Prelude.IsLeft p) x
- Predicate.Prelude: instance forall k (p :: k) x a b. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a b) => Predicate.Core.P (Predicate.Prelude.IsRight p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a) => Predicate.Core.P (Predicate.Prelude.IsJust p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a) => Predicate.Core.P (Predicate.Prelude.IsNothing p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.NonEmpty a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Base.Semigroup a) => Predicate.Core.P (Predicate.Prelude.SConcat p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P p x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.Ones p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P p x, GHC.Show.Show a, GHC.Base.Monoid a) => Predicate.Core.P (Predicate.Prelude.MConcat p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.MkJust p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Prelude.Prime p) x
- Predicate.Prelude: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Prelude.PrimeNext p) x
- Predicate.Prelude: instance forall k (p :: k) x s. (Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x, GHC.Show.Show s, GHC.Show.Show (Control.Lens.Wrapped.Unwrapped s), Control.Lens.Wrapped.Wrapped s) => Predicate.Core.P (Predicate.Prelude.Unwrap p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Data.Aeson.Types.ToJSON.ToJSON (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.EncodeJson p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Abs p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Negate p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Signum p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ShowP p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL1T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL1C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.Fst p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL2T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL2C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.Snd p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL3T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL3C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.Thd p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL4T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL4C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.L4 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL5T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL5C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.L5 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Prelude.ExtractL6T (Predicate.Core.PP p x)), Predicate.Prelude.ExtractL6C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.L6 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Prelude.ToDayC (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.ToDay p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Prelude.ToTimeC (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Prelude.ToTime p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day) => Predicate.Core.P (Predicate.Prelude.ToWeekDate p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day) => Predicate.Core.P (Predicate.Prelude.ToWeekYear p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ (GHC.Base.String -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReplaceFn2 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ (GHC.Base.String -> [GHC.Base.String] -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReplaceFn1 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ ([GHC.Base.String] -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReplaceFn3 p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.UnMkDay p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Clock.Internal.UTCTime.UTCTime, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.UTCTimeToPosix p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.UnMkTime p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReadDir p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReadEnv p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReadFile p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Real.Rational, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.PosixToUTCTime p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.IdBool p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Not p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ [GHC.Types.Int], Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Luhn p) x
- Predicate.Prelude: instance forall k (p :: k) x. (Predicate.Prelude.ToStringC (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ToString p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.DirExistsT p) x => Predicate.Core.P (Predicate.Prelude.DirExists p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.Fail Predicate.Core.I p) x => Predicate.Core.P (Predicate.Prelude.FailS p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.Fail Predicate.Prelude.Unproxy p) x => Predicate.Core.P (Predicate.Prelude.Failp p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.FileExistsT p) x => Predicate.Core.P (Predicate.Prelude.FileExists p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.FirstT p) x => Predicate.Core.P (Predicate.Prelude.First p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.IsThatT p) x => Predicate.Core.P (Predicate.Prelude.IsThat p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.IsTheseT p) x => Predicate.Core.P (Predicate.Prelude.IsThese p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.IsThisT p) x => Predicate.Core.P (Predicate.Prelude.IsThis p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.L1T p) x => Predicate.Core.P (Predicate.Prelude.L1 p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.L2T p) x => Predicate.Core.P (Predicate.Prelude.L2 p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.L3T p) x => Predicate.Core.P (Predicate.Prelude.L3 p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.LeftT' p) x => Predicate.Core.P (Predicate.Prelude.Left' p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkDayExtraT p) x => Predicate.Core.P (Predicate.Prelude.MkDayExtra p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkDayT p) x => Predicate.Core.P (Predicate.Prelude.MkDay p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkTimeT p) x => Predicate.Core.P (Predicate.Prelude.MkTime p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.OrdA' p p) x => Predicate.Core.P (Predicate.Prelude.OrdA p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.RightT' p) x => Predicate.Core.P (Predicate.Prelude.Right' p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.StderrT p) x => Predicate.Core.P (Predicate.Prelude.Stderr p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.StdoutT p) x => Predicate.Core.P (Predicate.Prelude.Stdout p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.ThatT' p) x => Predicate.Core.P (Predicate.Prelude.That' p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.TheseT' p) x => Predicate.Core.P (Predicate.Prelude.These' p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.ThisT' p) x => Predicate.Core.P (Predicate.Prelude.This' p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.TrimBothT p) x => Predicate.Core.P (Predicate.Prelude.TrimBoth p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.TrimLT p) x => Predicate.Core.P (Predicate.Prelude.TrimL p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Prelude.TrimRT p) x => Predicate.Core.P (Predicate.Prelude.TrimR p) x
- Predicate.Prelude: instance forall k (p :: k) x. Predicate.Core.P p x => Predicate.Core.P (Predicate.Prelude.Singleton p) x
- Predicate.Prelude: instance forall k (ps :: [k]) a. Predicate.Core.P (Predicate.Prelude.DoExpandT ps) a => Predicate.Core.P (Predicate.Prelude.Do ps) a
- Predicate.Prelude: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Prelude.CatMaybesT q) x => Predicate.Core.P (Predicate.Prelude.CatMaybes q) x
- Predicate.Prelude: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Prelude.PredBT' q) x => Predicate.Core.P (Predicate.Prelude.PredB' q) x
- Predicate.Prelude: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Prelude.ScanNAT q) x => Predicate.Core.P (Predicate.Prelude.ScanNA q) x
- Predicate.Prelude: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Prelude.SecondT q) x => Predicate.Core.P (Predicate.Prelude.Second q) x
- Predicate.Prelude: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Prelude.SuccBT' q) x => Predicate.Core.P (Predicate.Prelude.SuccB' q) x
- Predicate.Prelude: instance forall k (r :: Predicate.Util.ReplaceFnSub) (p :: k) x. (Predicate.Util.GetReplaceFnSub r, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReplaceFn r p) x
- Predicate.Prelude: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Prelude.AppendFileT s p) x => Predicate.Core.P (Predicate.Prelude.AppendFile s p) x
- Predicate.Prelude: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Prelude.WriteFileT s p) x => Predicate.Core.P (Predicate.Prelude.WriteFile s p) x
- Predicate.Prelude: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Prelude.WriteFileT' s p) x => Predicate.Core.P (Predicate.Prelude.WriteFile' s p) x
- Predicate.Prelude: instance forall k (t :: * -> *) (p :: k) x a. (Data.Foldable.Foldable t, Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.OneP p) x
- Predicate.Prelude: instance forall k (t :: * -> *) a (p :: k) x. (GHC.Show.Show (t a), Data.Foldable.Foldable t, t a Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Null' p) x
- Predicate.Prelude: instance forall k (t :: k) a. (GHC.Show.Show (Predicate.Core.PP t a), GHC.Base.Monoid (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Prelude.MEmptyT' t) a
- Predicate.Prelude: instance forall k (t :: k) a. Predicate.Core.P (Predicate.Prelude.MkNothing' t) a
- Predicate.Prelude: instance forall k (t :: k) x. Predicate.Core.P (Predicate.Prelude.EmptyList' t) x
- Predicate.Prelude: instance forall k (t :: k) x. Predicate.Core.P (Predicate.Prelude.ProxyT' t) x
- Predicate.Prelude: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.FromEnum p) x
- Predicate.Prelude: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Pred p) x
- Predicate.Prelude: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Succ p) x
- Predicate.Prelude: instance forall k a (p :: k) x. (GHC.Show.Show a, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Just p) x
- Predicate.Prelude: instance forall k a (p :: k) x. (a Data.Type.Equality.~ Predicate.Core.PP p x, GHC.Show.Show a, GHC.Real.Real a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ToRational p) x
- Predicate.Prelude: instance forall k a (p :: k). (GHC.Show.Show a, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.GuardSimple p) a
- Predicate.Prelude: instance forall k a (t :: * -> *) (p :: k) x. (GHC.Show.Show a, GHC.Show.Show (t [a]), Predicate.Core.PP p x Data.Type.Equality.~ t [a], Predicate.Core.P p x, Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Prelude.Concat p) x
- Predicate.Prelude: instance forall k a x (ps :: [k]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Prelude.ParaImpl (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Prelude.Para ps) x
- Predicate.Prelude: instance forall k k1 (p :: k -> k1) (q :: k) a. Predicate.Core.P (p q) a => Predicate.Core.P (p Predicate.Prelude.$ q) a
- Predicate.Prelude: instance forall k k1 (p :: k -> k1) (q :: k) a. Predicate.Core.P (p q) a => Predicate.Core.P (q Predicate.Prelude.& p) a
- Predicate.Prelude: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Prelude.BoolsImpl (Predicate.Util.LenT ps) ps) x, Predicate.Core.PP (Predicate.Prelude.BoolsImpl (Predicate.Util.LenT ps) ps) x Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.Bools ps) x
- Predicate.Prelude: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Prelude.GuardsImpl (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Prelude.Guards ps) x
- Predicate.Prelude: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Prelude.GuardsImplX (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Prelude.GuardsDetailImpl ps) x
- Predicate.Prelude: instance forall k s (p :: k) x. (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Head p) x
- Predicate.Prelude: instance forall k s (p :: k) x. (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Last p) x
- Predicate.Prelude: instance forall k s (p :: k) x. (GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Tail p) x
- Predicate.Prelude: instance forall k s (p :: k) x. (GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.Init p) x
- Predicate.Prelude: instance forall k t (def :: k) x. Predicate.Core.P (Predicate.Prelude.ToEnumBDefT t def) x => Predicate.Core.P (Predicate.Prelude.ToEnumBDef t def) x
- Predicate.Prelude: instance forall k t (n :: GHC.Types.Nat) (p :: k) x. Predicate.Core.P (Predicate.Prelude.ReadBaseT t n p) x => Predicate.Core.P (Predicate.Prelude.ReadBase t n p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.CeilingT t p) x => Predicate.Core.P (Predicate.Prelude.Ceiling t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.Fail (Predicate.Prelude.Hole t) p) x => Predicate.Core.P (Predicate.Prelude.Failt t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FloorT t p) x => Predicate.Core.P (Predicate.Prelude.Floor t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FoldMapT t p) x => Predicate.Core.P (Predicate.Prelude.FoldMap t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FromIntegerT t p) x => Predicate.Core.P (Predicate.Prelude.FromInteger t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FromIntegralT t p) x => Predicate.Core.P (Predicate.Prelude.FromIntegral t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FromRationalT t p) x => Predicate.Core.P (Predicate.Prelude.FromRational t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.FromStringPT t p) x => Predicate.Core.P (Predicate.Prelude.FromString t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.IToListT t p) x => Predicate.Core.P (Predicate.Prelude.IToList t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkLeftT t p) x => Predicate.Core.P (Predicate.Prelude.MkLeft t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkRightT t p) x => Predicate.Core.P (Predicate.Prelude.MkRight t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkThatT t p) x => Predicate.Core.P (Predicate.Prelude.MkThat t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.MkThisT t p) x => Predicate.Core.P (Predicate.Prelude.MkThis t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ParseJsonFileT t p) x => Predicate.Core.P (Predicate.Prelude.ParseJsonFile t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ParseJsonT t p) x => Predicate.Core.P (Predicate.Prelude.ParseJson t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ReadMaybeT t p) x => Predicate.Core.P (Predicate.Prelude.ReadMaybe t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ReadPT t p) x => Predicate.Core.P (Predicate.Prelude.ReadP t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ReadQT t p) x => Predicate.Core.P (Predicate.Prelude.ReadQ t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.ToEnumT t p) x => Predicate.Core.P (Predicate.Prelude.ToEnum t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.TruncateT t p) x => Predicate.Core.P (Predicate.Prelude.Truncate t p) x
- Predicate.Prelude: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Prelude.WrapT t p) x => Predicate.Core.P (Predicate.Prelude.Wrap t p) x
- Predicate.Prelude: instance forall k x1 x2 (p :: k) x a b (th :: Data.These.These x1 x2). (Predicate.Core.PP p x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, GHC.Show.Show a, GHC.Show.Show b, Predicate.Util.GetThese th) => Predicate.Core.P (Predicate.Prelude.IsTh th p) x
- Predicate.Prelude: instance forall k0 k k1 k2 (r :: k2) x (q :: k1) (p :: k) (n :: GHC.Types.Nat) (e :: k0). (Predicate.Core.P r x, Predicate.Core.P q (Predicate.Core.PP r x), GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP r x)), Predicate.Core.P p (Predicate.Core.PP r x), Predicate.Core.PP p (Predicate.Core.PP r x) Data.Type.Equality.~ GHC.Types.Bool, GHC.TypeNats.KnownNat n, GHC.Show.Show (Predicate.Core.PP r x), Predicate.Core.P e (Predicate.Core.PP r x, Data.Proxy.Proxy (Predicate.Core.PP q (Predicate.Core.PP r x))), Predicate.Core.PP e (Predicate.Core.PP r x, Data.Proxy.Proxy (Predicate.Core.PP q (Predicate.Core.PP r x))) Data.Type.Equality.~ Predicate.Core.PP q (Predicate.Core.PP r x)) => Predicate.Core.P (Predicate.Prelude.CaseImpl n e '[p] '[q] r) x
- Predicate.Prelude: instance forall k0 k1 k (prt :: k) (ps :: [(k0, k1)]) x. Predicate.Core.P (Predicate.Prelude.GuardsDetailT prt ps) x => Predicate.Core.P (Predicate.Prelude.GuardsDetail prt ps) x
- Predicate.Prelude: instance forall k0 k1 k2 k (n :: GHC.Types.Nat) (ps :: [k]) (r :: k2) x (p :: k) (q :: k1) (e :: k0) (p1 :: k) (q1 :: k1) (qs :: [k1]). (GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P r x, Predicate.Core.P p (Predicate.Core.PP r x), Predicate.Core.P q (Predicate.Core.PP r x), Predicate.Core.PP p (Predicate.Core.PP r x) Data.Type.Equality.~ GHC.Types.Bool, GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP r x)), GHC.Show.Show (Predicate.Core.PP r x), Predicate.Core.P (Predicate.Prelude.CaseImpl n e (p1 : ps) (q1 : qs) r) x, Predicate.Core.PP (Predicate.Prelude.CaseImpl n e (p1 : ps) (q1 : qs) r) x Data.Type.Equality.~ Predicate.Core.PP q (Predicate.Core.PP r x)) => Predicate.Core.P (Predicate.Prelude.CaseImpl n e (p : p1 : ps) (q : q1 : qs) r) x
- Predicate.Prelude: instance forall k1 k (p :: k) a (q :: k1). Predicate.Core.P p a => Predicate.Core.P (Predicate.Prelude.K p q) a
- Predicate.Prelude: instance forall k1 k (prt :: k) (ps :: [k1]) x. (Predicate.Core.PP (Predicate.Prelude.Bools (Predicate.Prelude.ToGuardsT prt ps)) x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Prelude.BoolsQuickT prt ps) x) => Predicate.Core.P (Predicate.Prelude.BoolsQuick prt ps) x
- Predicate.Prelude: instance forall k1 k (prt :: k) (ps :: [k1]) x. Predicate.Core.P (Predicate.Prelude.GuardsQuickT prt ps) x => Predicate.Core.P (Predicate.Prelude.GuardsQuick prt ps) x
- Predicate.Prelude: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt (GHC.Types.Int, a) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt (GHC.Types.Int, a), GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Prelude.BoolsImpl n ps) x, Predicate.Core.PP (Predicate.Prelude.BoolsImpl n ps) [a] Data.Type.Equality.~ GHC.Types.Bool, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Prelude.BoolsImpl n ('(prt, p) : ps)) x
- Predicate.Prelude: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt (GHC.Types.Int, a) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt (GHC.Types.Int, a), GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Prelude.GuardsImpl n ps) [a], Predicate.Core.PP (Predicate.Prelude.GuardsImpl n ps) [a] Data.Type.Equality.~ [a], GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Prelude.GuardsImpl n ('(prt, p) : ps)) x
- Predicate.Prelude: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt a, GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Prelude.GuardsImplX n ps) [a], Predicate.Core.PP (Predicate.Prelude.GuardsImplX n ps) [a] Data.Type.Equality.~ [a], GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Prelude.GuardsImplX n ('(prt, p) : ps)) x
- Predicate.Prelude: instance forall k1 k x a (prt :: k) (n :: GHC.Types.Nat) (p :: k1). (x Data.Type.Equality.~ [a], Predicate.Core.P (Predicate.Prelude.BoolsNT prt n p) x) => Predicate.Core.P (Predicate.Prelude.BoolsN prt n p) x
- Predicate.Prelude: instance forall k1 k2 (def :: k2) (t :: k1) a. (Predicate.Core.P def (Data.Proxy.Proxy (Predicate.Core.PP t a)), Predicate.Core.PP def (Data.Proxy.Proxy (Predicate.Core.PP t a)) Data.Type.Equality.~ Predicate.Core.PP t a, GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Enum.Bounded (Predicate.Core.PP t a), GHC.Enum.Enum (Predicate.Core.PP t a), GHC.Real.Integral a) => Predicate.Core.P (Predicate.Prelude.ToEnumBDef' t def) a
- Predicate.Prelude: instance forall k1 k2 (ignore :: GHC.Types.Bool) (p :: k2) x (q :: k1) (cmp :: GHC.Types.Ordering). (Predicate.Util.GetBool ignore, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Util.GetOrdering cmp) => Predicate.Core.P (Predicate.Prelude.IsFixImpl cmp ignore p q) x
- Predicate.Prelude: instance forall k1 k2 (keep :: GHC.Types.Bool) a (p :: k2) x (q :: k1). (Predicate.Util.GetBool keep, GHC.Classes.Eq a, GHC.Show.Show a, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.PP q x Data.Type.Equality.~ [a]) => Predicate.Core.P (Predicate.Prelude.KeepImpl keep p q) x
- Predicate.Prelude: instance forall k1 k2 (l :: GHC.Types.Bool) (p :: k2) x (q :: k1). (Predicate.Util.GetBool l, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Data.Text.Lens.IsText (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.StripImpl l p q) x
- Predicate.Prelude: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.HeadFailT msg q) x => Predicate.Core.P (Predicate.Prelude.HeadFail msg q) x
- Predicate.Prelude: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.InitFailT msg q) x => Predicate.Core.P (Predicate.Prelude.InitFail msg q) x
- Predicate.Prelude: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.LastFailT msg q) x => Predicate.Core.P (Predicate.Prelude.LastFail msg q) x
- Predicate.Prelude: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.TailFailT msg q) x => Predicate.Core.P (Predicate.Prelude.TailFail msg q) x
- Predicate.Prelude: instance forall k1 k2 (n :: GHC.Types.Nat) bs b a (s :: k2) x (p :: k1). (GHC.TypeNats.KnownNat n, Predicate.Prelude.PrintC bs, (b, bs) Data.Type.Equality.~ Predicate.Util.InductListP n a, Predicate.Util.InductListC n a, Text.Printf.PrintfArg b, Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P s x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.PrintL n s p) x
- Predicate.Prelude: instance forall k1 k2 (n :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Prelude.IterateNT n f) x => Predicate.Core.P (Predicate.Prelude.IterateN n f) x
- Predicate.Prelude: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.DropT n p) x => Predicate.Core.P (Predicate.Prelude.Drop n p) x
- Predicate.Prelude: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.RotateT n p) x => Predicate.Core.P (Predicate.Prelude.Rotate n p) x
- Predicate.Prelude: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.TakeT n p) x => Predicate.Core.P (Predicate.Prelude.Take n p) x
- Predicate.Prelude: instance forall k1 k2 (n :: k2) a (p :: k1). (Predicate.Core.P n a, GHC.Real.Integral (Predicate.Core.PP n a), GHC.Base.Semigroup (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.STimes n p) a
- Predicate.Prelude: instance forall k1 k2 (ns :: k2) x (p :: k1) a n. (Predicate.Core.P ns x, Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ [a], GHC.Show.Show n, GHC.Show.Show a, Predicate.Core.PP ns x Data.Type.Equality.~ [n], GHC.Real.Integral n) => Predicate.Core.P (Predicate.Prelude.SplitAts ns p) x
- Predicate.Prelude: instance forall k1 k2 (o :: Predicate.Util.OrderingP) (p :: k2) a (q :: k1). (Predicate.Util.GetOrd o, GHC.Classes.Ord (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.Cmp o p q) a
- Predicate.Prelude: instance forall k1 k2 (op :: Predicate.Prelude.BinOp) (p :: k2) a (q :: k1). (Predicate.Prelude.GetBinOp op, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Num.Num (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.Bin op p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Prelude.IterateUntilT p f) x => Predicate.Core.P (Predicate.Prelude.IterateUntil p f) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Prelude.IterateWhileT p f) x => Predicate.Core.P (Predicate.Prelude.IterateWhile p f) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) a. Predicate.Core.P (Predicate.Prelude.BangBangQT p q) a => Predicate.Core.P (p Predicate.Prelude.!!? q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) a. Predicate.Core.P (Predicate.Prelude.BangBangT p q) a => Predicate.Core.P (p Predicate.Prelude.!! q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.AddT p q) x => Predicate.Core.P (p Predicate.Prelude.+ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.AndAT p q) x => Predicate.Core.P (p Predicate.Prelude.&* q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ArrowRT p q) x => Predicate.Core.P (p Predicate.Prelude.*> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.BetweenT p q) x => Predicate.Core.P (p Predicate.Prelude.<..> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CEq p q) x => Predicate.Core.P (p Predicate.Prelude.== q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CGe p q) x => Predicate.Core.P (p Predicate.Prelude.>= q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CGt p q) x => Predicate.Core.P (p Predicate.Prelude.> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CLe p q) x => Predicate.Core.P (p Predicate.Prelude.<= q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CLt p q) x => Predicate.Core.P (p Predicate.Prelude.< q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.Cmp 'Predicate.Util.CNe p q) x => Predicate.Core.P (p Predicate.Prelude./= q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CEq p q) x => Predicate.Core.P (p Predicate.Prelude.==~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CGe p q) x => Predicate.Core.P (p Predicate.Prelude.>=~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CGt p q) x => Predicate.Core.P (p Predicate.Prelude.>~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CLe p q) x => Predicate.Core.P (p Predicate.Prelude.<=~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CLt p q) x => Predicate.Core.P (p Predicate.Prelude.<~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.CmpI 'Predicate.Util.CNe p q) x => Predicate.Core.P (p Predicate.Prelude./=~ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ConcatMapT p q) x => Predicate.Core.P (Predicate.Prelude.ConcatMap p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.EnumFromToT p q) x => Predicate.Core.P (p Predicate.Prelude.... q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.FilterT p q) x => Predicate.Core.P (Predicate.Prelude.Filter p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.HeadDefT p q) x => Predicate.Core.P (Predicate.Prelude.HeadDef p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.InitDefT p q) x => Predicate.Core.P (Predicate.Prelude.InitDef p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsInfixIT p q) x => Predicate.Core.P (Predicate.Prelude.IsInfixI p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsInfixT p q) x => Predicate.Core.P (Predicate.Prelude.IsInfix p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsPrefixIT p q) x => Predicate.Core.P (Predicate.Prelude.IsPrefixI p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsPrefixT p q) x => Predicate.Core.P (Predicate.Prelude.IsPrefix p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsSuffixIT p q) x => Predicate.Core.P (Predicate.Prelude.IsSuffixI p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.IsSuffixT p q) x => Predicate.Core.P (Predicate.Prelude.IsSuffix p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.KeepT p q) x => Predicate.Core.P (Predicate.Prelude.Keep p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.LastDefT p q) x => Predicate.Core.P (Predicate.Prelude.LastDef p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.LeftArrowsT p q) x => Predicate.Core.P (p Predicate.Prelude.<< q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.MapMaybeT p q) x => Predicate.Core.P (Predicate.Prelude.MapMaybe p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.MultT p q) x => Predicate.Core.P (p Predicate.Prelude.* q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.NegateRatioT p q) x => Predicate.Core.P (p Predicate.Prelude.-% q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.OrAT p q) x => Predicate.Core.P (p Predicate.Prelude.|+ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.OrdAT' p q) x => Predicate.Core.P (Predicate.Prelude.OrdA' p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.QuotT p q) x => Predicate.Core.P (Predicate.Prelude.Quot p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ReT p q) x => Predicate.Core.P (Predicate.Prelude.Re p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.RemT p q) x => Predicate.Core.P (Predicate.Prelude.Rem p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.RemoveT p q) x => Predicate.Core.P (Predicate.Prelude.Remove p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.RescanRangesT p q) x => Predicate.Core.P (Predicate.Prelude.RescanRanges p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.RescanT p q) x => Predicate.Core.P (Predicate.Prelude.Rescan p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ResplitT p q) x => Predicate.Core.P (Predicate.Prelude.Resplit p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SkipBothT p q) x => Predicate.Core.P (p Predicate.Prelude.>|> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SkipLT p q) x => Predicate.Core.P (p Predicate.Prelude.|> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SkipRT p q) x => Predicate.Core.P (p Predicate.Prelude.>| q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SortOnDescT p q) x => Predicate.Core.P (Predicate.Prelude.SortOnDesc p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SortOnT p q) x => Predicate.Core.P (Predicate.Prelude.SortOn p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SpanT p q) x => Predicate.Core.P (Predicate.Prelude.Span p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.StripLT p q) x => Predicate.Core.P (Predicate.Prelude.StripL p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.StripRT p q) x => Predicate.Core.P (Predicate.Prelude.StripR p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.SubT p q) x => Predicate.Core.P (p Predicate.Prelude.- q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.TailDefT p q) x => Predicate.Core.P (Predicate.Prelude.TailDef p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.TheseIdT p q) x => Predicate.Core.P (Predicate.Prelude.TheseId p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.TraverseT p q) x => Predicate.Core.P (Predicate.Prelude.Traverse p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.WAmpT p q) x => Predicate.Core.P (p Predicate.Prelude.&&& q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) (s :: k1) x. Predicate.Core.P (Predicate.Prelude.CatchT' p s) x => Predicate.Core.P (Predicate.Prelude.Catch' p s) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (b :: k1). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P b a, Predicate.Core.P p a, Predicate.Core.PP b a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.MaybeBool b p) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (o :: Predicate.Util.OrderingP) (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Util.GetOrd o, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.CmpI o p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q b), Predicate.Core.P p a, Predicate.Core.P q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Prelude.*** q) (a, b)
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q b), Predicate.Core.P p a, Predicate.Core.P q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Prelude.+++ q) (Data.Either.Either a b)
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Prelude.||| q) (Data.Either.Either a b)
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, GHC.Show.Show (f a), Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Prelude.Map p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Prelude.All p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Prelude.Any p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1) x. (Predicate.Core.P p (a, a), Predicate.Core.P q x, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ [a], Predicate.Core.PP p (a, a) Data.Type.Equality.~ GHC.Types.Ordering) => Predicate.Core.P (Predicate.Prelude.SortBy p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (GHC.Classes.Ord (Predicate.Core.PP p a), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.P q a) => Predicate.Core.P (p Predicate.Prelude.==! q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP p a)), Predicate.Core.P p a, Predicate.Core.P q (Predicate.Core.PP p a)) => Predicate.Core.P (p Predicate.Prelude.>> q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q a)) => Predicate.Core.P (Predicate.Prelude.MkThese p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q a), GHC.Num.Num (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP q a)) => Predicate.Core.P (p Predicate.Prelude.^ q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Prelude.&& q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Prelude.&&~ q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Prelude.|| q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Prelude.||~ q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Prelude.~> q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (p Predicate.Prelude.===~ q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, GHC.Classes.Eq (Predicate.Core.PP q a), Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Fractional (Predicate.Core.PP p a)) => Predicate.Core.P (p Predicate.Prelude./ q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Float.Floating (Predicate.Core.PP p a), GHC.Classes.Ord (Predicate.Core.PP q a)) => Predicate.Core.P (p Predicate.Prelude.** q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.Div p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.DivMod p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.Mod p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.QuotRem p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP q a), GHC.Float.Floating (Predicate.Core.PP q a), GHC.Classes.Ord (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.LogBase p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a (q :: k1). ([Predicate.Core.PP p a] Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Classes.Eq (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.Elem p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a b (n :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ [b], Predicate.Core.P n a, Predicate.Core.P p a, GHC.Show.Show b, GHC.Real.Integral (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Prelude.ChunksOf n p) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a b (n :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ [b], Predicate.Core.P n a, Predicate.Core.P p a, GHC.Show.Show b, GHC.Real.Integral (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Prelude.SplitAt n p) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a x (q :: k1) b. (Predicate.Core.PP p (a, x) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.P p (a, x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.RightFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a x (q :: k1) y. (Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Prelude.Zip p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) a x (q :: k1) y. (Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Prelude.ZipThese p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) b x (q :: k1) a. (Predicate.Core.PP p (b, x) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.P p (b, x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.LeftFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) (t :: * -> *) b. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (t b), GHC.Base.Alternative t, t b Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP q x Data.Type.Equality.~ t b) => Predicate.Core.P (p Predicate.Prelude.<|> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) (t :: * -> *) c. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Base.Functor t, Predicate.Core.PP q x Data.Type.Equality.~ t c, Predicate.Prelude.ApplyConstT (Predicate.Core.PP q x) (Predicate.Core.PP p x) Data.Type.Equality.~ t (Predicate.Core.PP p x)) => Predicate.Core.P (p Predicate.Prelude.<$ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ (a -> b), Predicate.Prelude.FnT (Predicate.Core.PP p x) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Prelude.$$ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ (a -> b), Predicate.Prelude.FnT (Predicate.Core.PP p x) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (q Predicate.Prelude.$& p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.ThatFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.TheseFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.ThisFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, GHC.Show.Show x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.Partition p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.PP q x Data.Type.Equality.~ [a]) => Predicate.Core.P (p Predicate.Prelude.++ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Prelude.EnumFromTo p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.Break p q) a
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Maybe.Maybe a, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.JustFail p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (GHC.Base.Semigroup (Predicate.Core.PP p x), Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (p Predicate.Prelude.<> q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (GHC.Real.Integral (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP q x), GHC.Classes.Eq (Predicate.Core.PP q x), Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP q x)) => Predicate.Core.P (p Predicate.Prelude.% q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q ((GHC.Base.String, x), Data.Proxy.Proxy (Predicate.Core.PP p x)), Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q ((GHC.Base.String, x), Data.Proxy.Proxy (Predicate.Core.PP p x))) => Predicate.Core.P (Predicate.Prelude.Catch p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP q x), Control.Lens.Cons.Cons (Predicate.Core.PP q x) (Predicate.Core.PP q x) (Predicate.Core.PP p x) (Predicate.Core.PP p x)) => Predicate.Core.P (p Predicate.Prelude.:+ q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP q x), GHC.Show.Show (Predicate.Core.PP p x), Control.Lens.Cons.Snoc (Predicate.Core.PP p x) (Predicate.Core.PP p x) (Predicate.Core.PP q x) (Predicate.Core.PP q x)) => Predicate.Core.P (p Predicate.Prelude.+: q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Time.Format.FormatTime (Predicate.Core.PP q x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.FormatTimeP p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Data.Aeson.Types.ToJSON.ToJSON (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.EncodeJsonFile p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (s :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, Control.Lens.Wrapped.Unwrapped (Predicate.Core.PP s x) Data.Type.Equality.~ Predicate.Core.PP p x, Control.Lens.Wrapped.Wrapped (Predicate.Core.PP s x), GHC.Show.Show (Predicate.Core.PP s x)) => Predicate.Core.P (Predicate.Prelude.Wrap' s p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (s :: k1). (Text.Printf.PrintfArg (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P s x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.PrintF s p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.MkLeft' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.MkRight' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.MkThat' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.MkThis' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.Ceiling' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.Floor' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.Truncate' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.ByteString.Lazy.Internal.ByteString, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Data.Aeson.Types.FromJSON.FromJSON (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.ParseJson' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Data.Aeson.Types.FromJSON.FromJSON (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.ParseJsonFile' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Read.Read (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.ReadMaybe' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Read.Read (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Prelude.ReadP' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x a (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.PP q x Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.Intercalate p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x a (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Maybe.Maybe a, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.JustDef p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x a (t :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Enum.Enum (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.Integral a) => Predicate.Core.P (Predicate.Prelude.ToEnum' t p) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x a a' (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ (a, a'), Predicate.Core.P q x, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Classes.Ord a, a Data.Type.Equality.~ a', GHC.Show.Show a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.BetweenA p q) x
- Predicate.Prelude: instance forall k1 k2 (p :: k2) x t (q :: k1) a. (Predicate.Core.P p x, GHC.Classes.Ord t, GHC.Show.Show x, GHC.Show.Show t, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ t, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.PartitionBy t p q) a
- Predicate.Prelude: instance forall k1 k2 (prt :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.ExitWhenT prt p) x => Predicate.Core.P (Predicate.Prelude.ExitWhen prt p) x
- Predicate.Prelude: instance forall k1 k2 (prt :: k2) a (t :: k1). (Predicate.Core.P prt a, Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Prelude.Fail t prt) a
- Predicate.Prelude: instance forall k1 k2 (q :: k2) a (p :: k1). (Predicate.Core.P q a, GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.PP p (Data.Proxy.Proxy (Predicate.Core.PP q a)) Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p (Data.Proxy.Proxy (Predicate.Core.PP q a))) => Predicate.Core.P (Predicate.Prelude.MaybeIn p q) (GHC.Maybe.Maybe a)
- Predicate.Prelude: instance forall k1 k2 (q :: k2) a (p :: k1). (Predicate.Core.P q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a), Control.Lens.At.Ixed (Predicate.Core.PP p a), Predicate.Core.PP q a Data.Type.Equality.~ Control.Lens.At.Index (Predicate.Core.PP p a), GHC.Show.Show (Control.Lens.At.Index (Predicate.Core.PP p a)), GHC.Show.Show (Control.Lens.At.IxValue (Predicate.Core.PP p a))) => Predicate.Core.P (Predicate.Prelude.Lookup p q) a
- Predicate.Prelude: instance forall k1 k2 (q :: k2) a s (p :: k1) b. (Predicate.Core.PP q a Data.Type.Equality.~ s, Predicate.Core.PP p s Data.Type.Equality.~ GHC.Maybe.Maybe (b, s), Predicate.Core.P q a, Predicate.Core.P p s, GHC.Show.Show s, GHC.Show.Show b) => Predicate.Core.P (Predicate.Prelude.Unfoldr p q) a
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x (p :: k1). (Predicate.Prelude.ExtractL1C (Predicate.Core.PP q x), Predicate.Prelude.ExtractL2C (Predicate.Core.PP q x), Predicate.Core.P p (Predicate.Prelude.ExtractL1T (Predicate.Core.PP q x)), Predicate.Core.P p (Predicate.Prelude.ExtractL2T (Predicate.Core.PP q x)), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.Both p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (Data.Proxy.Proxy a), Predicate.Core.PP p (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Classes.Eq a, GHC.Enum.Bounded a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Prelude.PredB p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (Data.Proxy.Proxy a), Predicate.Core.PP p (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Classes.Eq a, GHC.Enum.Bounded a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Prelude.SuccB p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: * -> * -> * -> *) (r :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ (a, b), Predicate.Core.PP (p a b (Predicate.Core.PP r x)) x Data.Type.Equality.~ Predicate.Core.PP (p (Predicate.Prelude.Fst Predicate.Core.Id) (Predicate.Prelude.Snd Predicate.Core.Id) (Predicate.Prelude.Thd Predicate.Core.Id)) (a, b, Predicate.Core.PP r x), Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.P (p (Predicate.Prelude.Fst Predicate.Core.Id) (Predicate.Prelude.Snd Predicate.Core.Id) (Predicate.Prelude.Thd Predicate.Core.Id)) (a, b, Predicate.Core.PP r x)) => Predicate.Core.P (Predicate.Prelude.Uncurry p q r) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (a, x) Data.Type.Equality.~ b, Predicate.Core.P q x, Predicate.Core.P p (a, x)) => Predicate.Core.P (Predicate.Prelude.RightDef p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (b, x) Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (b, x)) => Predicate.Core.P (Predicate.Prelude.LeftDef p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ (a, b), Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.TheseDef p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ThisDef p q) x
- Predicate.Prelude: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ b, Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ThatDef p q) x
- Predicate.Prelude: instance forall k1 k2 (r :: k2) a (t :: k1). (Predicate.Core.P r a, Predicate.Core.PP r a Data.Type.Equality.~ GHC.Real.Rational, GHC.Show.Show (Predicate.Core.PP t a), GHC.Real.Fractional (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Prelude.FromRational' t r) a
- Predicate.Prelude: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.Re' rs p q) x
- Predicate.Prelude: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.Rescan' rs p q) x
- Predicate.Prelude: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.RescanRanges' rs p q) x
- Predicate.Prelude: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Prelude.Resplit' rs p q) x
- Predicate.Prelude: instance forall k1 k2 (s :: k2) a (t :: k1). (Predicate.Core.P s a, Predicate.Core.PP s a Data.Type.Equality.~ GHC.Base.String, GHC.Show.Show (Predicate.Core.PP t a), Data.String.IsString (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Prelude.FromString' t s) a
- Predicate.Prelude: instance forall k1 k2 (t :: * -> *) c (p :: k2) x (q :: k1) b. (GHC.Show.Show (t c), Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (t b), GHC.Base.Applicative t, t b Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP q x Data.Type.Equality.~ t c) => Predicate.Core.P (p Predicate.Prelude.<* q) x
- Predicate.Prelude: instance forall k1 k2 (t :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.ReadQT' t p) x => Predicate.Core.P (Predicate.Prelude.ReadQ' t p) x
- Predicate.Prelude: instance forall k1 k2 (t :: k2) a (n :: k1). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP n a), Predicate.Core.P n a, GHC.Show.Show (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Prelude.FromInteger' t n) a
- Predicate.Prelude: instance forall k1 k2 (t :: k2) a (n :: k1). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP n a), Predicate.Core.P n a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Prelude.FromIntegral' t n) a
- Predicate.Prelude: instance forall k1 k2 (t :: k2) x (n :: GHC.Types.Nat) (p :: k1). (Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), Predicate.Util.ZwischenT 2 36 n, GHC.Show.Show (Predicate.Core.PP t x), GHC.Num.Num (Predicate.Core.PP t x), GHC.TypeNats.KnownNat n, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Prelude.ReadBase' t n p) x
- Predicate.Prelude: instance forall k1 k2 a (prt :: k2) (p :: k1). (GHC.Show.Show a, Predicate.Core.P prt a, Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.Guard prt p) a
- Predicate.Prelude: instance forall k1 k2 a (t :: * -> *) (p :: k2) x (n :: k1). (GHC.Show.Show a, GHC.Show.Show (t a), Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Real.Integral (Predicate.Core.PP n x), Predicate.Core.P n x, Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Prelude.Cycle n p) x
- Predicate.Prelude: instance forall k1 k2 bs b y (s :: k2) x (p :: k1). (Predicate.Prelude.PrintC bs, (b, bs) Data.Type.Equality.~ Predicate.Util.InductTupleP y, Predicate.Util.InductTupleC y, Text.Printf.PrintfArg b, Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p x Data.Type.Equality.~ y, Predicate.Core.P s x, Predicate.Core.P p x, Predicate.Prelude.CheckT (Predicate.Core.PP p x) Data.Type.Equality.~ 'GHC.Types.True) => Predicate.Core.P (Predicate.Prelude.PrintT s p) x
- Predicate.Prelude: instance forall k1 k2 k3 (b :: GHC.Types.Bool) (rs :: [Predicate.Util.ROpt]) (p :: k3) x (q :: k2) (r :: k1). (Predicate.Util.GetBool b, Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Predicate.Util.RReplace, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Prelude.ReplaceImpl b rs p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (l :: k3) a x (p :: k2) (q :: k1) y. (Predicate.Core.PP l a Data.Type.Equality.~ x, Predicate.Core.P l a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Prelude.ZipL l p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (msg :: k3) (v :: k2) (w :: k1) x. Predicate.Core.P (Predicate.Prelude.LookupFailT msg v w) x => Predicate.Core.P (Predicate.Prelude.LookupFail msg v w) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Prelude.IterateNUntilT n p f) x => Predicate.Core.P (Predicate.Prelude.IterateNUntil n p f) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Prelude.IterateNWhileT n p f) x => Predicate.Core.P (Predicate.Prelude.IterateNWhile n p f) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.FoldNT n p q) x => Predicate.Core.P (Predicate.Prelude.FoldN n p q) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.PadLT n p q) x => Predicate.Core.P (Predicate.Prelude.PadL n p q) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.PadRT n p q) x => Predicate.Core.P (Predicate.Prelude.PadR n p q) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ScanNT n p q) x => Predicate.Core.P (Predicate.Prelude.ScanN n p q) x
- Predicate.Prelude: instance forall k1 k2 k3 (n :: k3) a (left :: GHC.Types.Bool) (p :: k2) (q :: k1). (Predicate.Core.P n a, Predicate.Util.GetBool left, GHC.Real.Integral (Predicate.Core.PP n a), [Predicate.Core.PP p a] Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.PadImpl left n p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceAllStringT o p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceAllString o p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceOneStringT o p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceOneString o p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.FoldLT p q r) x => Predicate.Core.P (Predicate.Prelude.FoldL p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceAllT p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceAll p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceOneT p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceOne p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) a (q :: k2) (b :: k1). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.P q a, Predicate.Core.P b a, Predicate.Core.PP b a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Prelude.EitherBool b p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) b a (q :: k2) x (r :: k1). (Predicate.Core.PP p (b, a) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ b, Predicate.Core.PP r x Data.Type.Equality.~ [a], Predicate.Core.P p (b, a), Predicate.Core.P q x, Predicate.Core.P r x, GHC.Show.Show b, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.Scanl p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.PP r x Data.Type.Equality.~ a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Prelude.EnumFromThenTo p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Real.Rational) => Predicate.Core.P (Predicate.Prelude.MkTime' p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Types.Int) => Predicate.Core.P (Predicate.Prelude.MkDay' p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Types.Int) => Predicate.Core.P (Predicate.Prelude.MkDayExtra' p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (p :: k3) x (r :: k2) (q :: k1). (GHC.Classes.Ord (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP r x Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP r x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Prelude.Between p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (q :: k3) a (p :: k2) (r :: k1). (Predicate.Core.P q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a), Control.Lens.At.Ixed (Predicate.Core.PP p a), Predicate.Core.PP q a Data.Type.Equality.~ Control.Lens.At.Index (Predicate.Core.PP p a), GHC.Show.Show (Control.Lens.At.Index (Predicate.Core.PP p a)), GHC.Show.Show (Control.Lens.At.IxValue (Predicate.Core.PP p a)), Predicate.Core.P r (Data.Proxy.Proxy (Control.Lens.At.IxValue (Predicate.Core.PP p a))), Predicate.Core.PP r (Data.Proxy.Proxy (Control.Lens.At.IxValue (Predicate.Core.PP p a))) Data.Type.Equality.~ Control.Lens.At.IxValue (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Prelude.IxL p q r) a
- Predicate.Prelude: instance forall k1 k2 k3 (r :: k3) a (p :: k2) (q :: k1). (GHC.Show.Show (Predicate.Core.PP r a), Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a, Predicate.Core.P r a, Predicate.Core.PP q a Data.Type.Equality.~ Predicate.Core.PP r a) => Predicate.Core.P (Predicate.Prelude.If p q r) a
- Predicate.Prelude: instance forall k1 k2 k3 (r :: k3) a y (p :: k2) x (q :: k1). (Predicate.Core.PP r a Data.Type.Equality.~ y, Predicate.Core.P r a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Prelude.ZipR r p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (r :: k3) x (p :: k2) a (q :: k1) b c. (Predicate.Core.P r x, Predicate.Core.P p (x, a), Predicate.Core.P q (x, b), Predicate.Core.PP r x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (x, a) Data.Type.Equality.~ c, Predicate.Core.PP q (x, b) Data.Type.Equality.~ c) => Predicate.Core.P (Predicate.Prelude.EitherX p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (r :: k3) x a b (p :: k2) (q :: k1). (Predicate.Core.PP r x Data.Type.Equality.~ (a, b), Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q b Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Prelude.AndA p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (r :: k3) x a b (p :: k2) (q :: k1). (Predicate.Core.PP r x Data.Type.Equality.~ (a, b), Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q b Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Prelude.OrA p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceAllStringT' rs o p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceAllString' rs o p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceOneStringT' rs o p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceOneString' rs o p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceAllT' rs p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceAll' rs p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Prelude.ReplaceOneT' rs p q r) x => Predicate.Core.P (Predicate.Prelude.ReplaceOne' rs p q r) x
- Predicate.Prelude: instance forall k1 k2 k3 (t :: k3) a (p :: k2) (q :: k1). (Data.Time.Format.Parse.ParseTime (Predicate.Core.PP t a), Data.Typeable.Internal.Typeable (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP t a), Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Prelude.ParseTimeP' t p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (t :: k3) a (p :: k2) (q :: k1). (Data.Time.Format.Parse.ParseTime (Predicate.Core.PP t a), Data.Typeable.Internal.Typeable (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP t a), Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ [GHC.Base.String], Predicate.Core.PP q a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Prelude.ParseTimes' t p q) a
- Predicate.Prelude: instance forall k1 k2 k3 (v :: k3) (w :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Prelude.LookupDefT v w p) x => Predicate.Core.P (Predicate.Prelude.LookupDef v w p) x
- Predicate.Prelude: instance forall k1 k2 k3 a b (p :: k3) (q :: k2) (r :: k1). (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r (a, b), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q b, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP r (a, b), Predicate.Core.PP q b Data.Type.Equality.~ Predicate.Core.PP r (a, b)) => Predicate.Core.P (Predicate.Prelude.TheseIn p q r) (Data.These.These a b)
- Predicate.Prelude: instance forall k1 k2 k3 k4 (l :: k4) a x (r :: k3) y (p :: k2) (q :: k1). (Predicate.Core.PP l a Data.Type.Equality.~ x, Predicate.Core.PP r a Data.Type.Equality.~ y, Predicate.Core.P l a, Predicate.Core.P r a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Prelude.ZipPad l r p q) a
- Predicate.Prelude: instance forall k1 k2 k3 k4 (msg :: k4) (v :: k3) (w :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.LookupFailT' msg v w q) x => Predicate.Core.P (Predicate.Prelude.LookupFail' msg v w q) x
- Predicate.Prelude: instance forall k1 k2 k3 k4 (s :: k4) x (p :: k3) a (q :: k2) b (r :: k1) c. (Predicate.Core.P s x, Predicate.Core.P p (x, a), Predicate.Core.P q (x, b), Predicate.Core.P r (x, (a, b)), Predicate.Core.PP s x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p (x, a) Data.Type.Equality.~ c, Predicate.Core.PP q (x, b) Data.Type.Equality.~ c, Predicate.Core.PP r (x, (a, b)) Data.Type.Equality.~ c) => Predicate.Core.P (Predicate.Prelude.TheseX p q r s) x
- Predicate.Prelude: instance forall k1 k2 k3 k4 (v :: k4) (w :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.LookupDefT' v w p q) x => Predicate.Core.P (Predicate.Prelude.LookupDef' v w p q) x
- Predicate.Prelude: instance forall k1 k2 t (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ParseTimePT t p q) x => Predicate.Core.P (Predicate.Prelude.ParseTimeP t p q) x
- Predicate.Prelude: instance forall k1 k2 t (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Prelude.ParseTimesT t p q) x => Predicate.Core.P (Predicate.Prelude.ParseTimes t p q) x
- Predicate.Prelude: instance forall k1 k2 x (p :: k2) (t :: k1) (f :: * -> *) a. (GHC.Show.Show x, Predicate.Core.P p x, Data.Typeable.Internal.Typeable (Predicate.Core.PP t (Predicate.Core.PP p x)), GHC.Show.Show (Predicate.Core.PP t (Predicate.Core.PP p x)), Control.Lens.Indexed.FoldableWithIndex (Predicate.Core.PP t (Predicate.Core.PP p x)) f, Predicate.Core.PP p x Data.Type.Equality.~ f a, GHC.Show.Show a) => Predicate.Core.P (Predicate.Prelude.IToList' t p) x
- Predicate.Prelude: instance forall k1 k2 x (q :: k2) a (p :: k1). (GHC.Show.Show x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p (x, x) Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p (x, x), Predicate.Core.P q a) => Predicate.Core.P (Predicate.Prelude.GroupBy p q) a
- Predicate.Prelude: instance forall k1 k2 x a (prt :: k2) (n :: GHC.Types.Nat) (p :: k1). (x Data.Type.Equality.~ [a], Predicate.Core.P (Predicate.Prelude.GuardsNT prt n p) x) => Predicate.Core.P (Predicate.Prelude.GuardsN prt n p) x
- Predicate.Prelude: instance forall k2 k k0 k1 (n :: GHC.Types.Nat) (e :: k0) (p :: k) (ps :: [k]) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Prelude.CaseImpl n e (p : ps) '[] r) x
- Predicate.Prelude: instance forall k2 k0 k k1 (n :: GHC.Types.Nat) (e :: k0) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Prelude.CaseImpl n e '[] '[] r) x
- Predicate.Prelude: instance forall k2 k0 k1 k (ps :: [k]) (qs :: [k1]) (e :: k0) (r :: k2) x. (Predicate.Util.FailUnlessT (Predicate.Util.LenT ps Data.Type.Equality.== Predicate.Util.LenT qs) ((('GHC.TypeLits.Text "lengths are not the same " 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType (Predicate.Util.LenT ps)) 'GHC.TypeLits.:<>: 'GHC.TypeLits.Text " vs ") 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType (Predicate.Util.LenT qs)), Predicate.Core.P (Predicate.Prelude.CaseImplT e ps qs r) x) => Predicate.Core.P (Predicate.Prelude.Case e ps qs r) x
- Predicate.Prelude: instance forall k2 k1 k (ps :: [k]) (qs :: [k1]) (r :: k2) x. Predicate.Core.P (Predicate.Prelude.CaseT' ps qs r) x => Predicate.Core.P (Predicate.Prelude.Case' ps qs r) x
- Predicate.Prelude: instance forall k2 k1 k0 k (n :: GHC.Types.Nat) (e :: k0) (q :: k1) (qs :: [k1]) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Prelude.CaseImpl n e '[] (q : qs) r) x
- Predicate.Prelude: instance forall k2 k1 k4 k5 (s :: k5) (ps :: [k4]) (qs :: [k1]) (r :: k2) x. Predicate.Core.P (Predicate.Prelude.CaseT'' s ps qs r) x => Predicate.Core.P (Predicate.Prelude.Case'' s ps qs r) x
- Predicate.Prelude: swapC :: SwapC p => p a b -> p b a
- Predicate.Prelude: type EitherIn p q = p ||| q
- Predicate.Prelude: type Ge n = I >= n
- Predicate.Prelude: type Gt n = I > n
- Predicate.Prelude: type Le n = I <= n
- Predicate.Prelude: type Lt n = I < n
- Predicate.Prelude: type Ne n = I /= n
- Predicate.Prelude: type Negative = Lt 0
- Predicate.Prelude: type OrdI p q = p ===~ q
- Predicate.Prelude: type OrdP p q = p ==! q
- Predicate.Prelude: type Positive = Gt 0
- Predicate.Prelude: type ReadIO (t :: Type) = ReadIO' t "Enter value"
- Predicate.Prelude: type ReadIO' (t :: Type) s = Stdout (s <> ":") >> Stdin >> ReadP t Id
- Predicate.Prelude: type Same n = I == n
- Predicate.Prelude: type Tuple2 p = '(p !! 0, p !! 1)
- Predicate.Prelude: type Tuple3 p = '(p !! 0, p !! 1, p !! 2)
- Predicate.Prelude: type Tuple4 p = '(p !! 0, p !! 1, p !! 2, p !! 3)
- Predicate.Prelude: type Tuple5 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4)
- Predicate.Prelude: type Tuple6 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4, p !! 5)
- Predicate.Prelude: type p >>> q = p >> q
- Predicate.Util: prettyRational :: Rational -> String
+ Predicate.Core: class Bifunctor p => SwapC p
+ Predicate.Core: data (q :: k) & (p :: k -> k1)
+ Predicate.Core: data All p q
+ Predicate.Core: data Any p q
+ Predicate.Core: data Between p q r
+ Predicate.Core: data Coerce (t :: k)
+ Predicate.Core: data Do (ps :: [k])
+ Predicate.Core: data Fail t prt
+ Predicate.Core: data FailS p
+ Predicate.Core: data Failp p
+ Predicate.Core: data Failt (t :: Type) p
+ Predicate.Core: data Fst p
+ Predicate.Core: data Hole (t :: Type)
+ Predicate.Core: data IdBool p
+ Predicate.Core: data L1 p
+ Predicate.Core: data L2 p
+ Predicate.Core: data L3 p
+ Predicate.Core: data L4 p
+ Predicate.Core: data L5 p
+ Predicate.Core: data L6 p
+ Predicate.Core: data Len
+ Predicate.Core: data Length p
+ Predicate.Core: data Map p q
+ Predicate.Core: data MsgI prt p
+ Predicate.Core: data Not p
+ Predicate.Core: data OneP p
+ Predicate.Core: data Pure (t :: Type -> Type) p
+ Predicate.Core: data Snd p
+ Predicate.Core: data Swap
+ Predicate.Core: data Thd p
+ Predicate.Core: data Unproxy
+ Predicate.Core: data Unwrap p
+ Predicate.Core: data Width (n :: Nat) p
+ Predicate.Core: data Wrap (t :: Type) p
+ Predicate.Core: data Wrap' t p
+ Predicate.Core: data p << q
+ Predicate.Core: infix 4 <..>
+ Predicate.Core: infixl 1 &
+ Predicate.Core: infixr 0 $
+ Predicate.Core: infixr 1 <<
+ Predicate.Core: infixr 2 ||~
+ Predicate.Core: infixr 3 &&~
+ Predicate.Core: instance (GHC.Show.Show (p a b), Predicate.Core.SwapC p, GHC.Show.Show (p b a)) => Predicate.Core.P Predicate.Core.Swap (p a b)
+ Predicate.Core: instance (GHC.Show.Show a, GHC.Show.Show t, GHC.Types.Coercible t a) => Predicate.Core.P (Predicate.Core.Coerce t) a
+ Predicate.Core: instance (GHC.Show.Show a, as Data.Type.Equality.~ [a]) => Predicate.Core.P Predicate.Core.Len as
+ Predicate.Core: instance Data.Typeable.Internal.Typeable a => Predicate.Core.P Predicate.Core.Unproxy (Data.Proxy.Proxy a)
+ Predicate.Core: instance Data.Typeable.Internal.Typeable t => Predicate.Core.P (Predicate.Core.Hole t) a
+ Predicate.Core: instance Predicate.Core.ExtractL1C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL1C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL1C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL1C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL1C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.ExtractL2C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL2C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL2C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL2C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL2C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.ExtractL3C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL3C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL3C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL3C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL3C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.ExtractL4C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL4C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL4C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL4C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL4C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.ExtractL5C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL5C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL5C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL5C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL5C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.ExtractL6C (a, b)
+ Predicate.Core: instance Predicate.Core.ExtractL6C (a, b, c)
+ Predicate.Core: instance Predicate.Core.ExtractL6C (a, b, c, d)
+ Predicate.Core: instance Predicate.Core.ExtractL6C (a, b, c, d, e)
+ Predicate.Core: instance Predicate.Core.ExtractL6C (a, b, c, d, e, f)
+ Predicate.Core: instance Predicate.Core.SwapC (,)
+ Predicate.Core: instance Predicate.Core.SwapC Data.Either.Either
+ Predicate.Core: instance Predicate.Core.SwapC Data.These.These
+ Predicate.Core: instance forall a1 a2 (p :: a1) x. (GHC.Show.Show a2, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a2, Predicate.Core.P p x) => Predicate.Core.P ('GHC.Maybe.Just p) x
+ Predicate.Core: instance forall a1 b1 (p :: b1) x a2 b2. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a2 b2, Predicate.Core.P p x) => Predicate.Core.P ('Data.Either.Right p) x
+ Predicate.Core: instance forall a1 b1 (p :: b1) x a2 b2. (Predicate.Core.PP p x Data.Type.Equality.~ Data.These.These a2 b2, Predicate.Core.P p x) => Predicate.Core.P ('Data.These.That p) x
+ Predicate.Core: instance forall b1 a1 (p :: a1) x a2 b2. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a2 b2, Predicate.Core.P p x) => Predicate.Core.P ('Data.Either.Left p) x
+ Predicate.Core: instance forall b1 a1 (p :: a1) x a2 b2. (Predicate.Core.PP p x Data.Type.Equality.~ Data.These.These a2 b2, Predicate.Core.P p x) => Predicate.Core.P ('Data.These.This p) x
+ Predicate.Core: instance forall k (n :: GHC.Types.Nat) (p :: k) a. (GHC.TypeNats.KnownNat n, Predicate.Core.P p a) => Predicate.Core.P (Predicate.Core.Width n p) a
+ Predicate.Core: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Core.Length p) x
+ Predicate.Core: instance forall k (p :: k) x (t :: * -> *). (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (t (Predicate.Core.PP p x)), GHC.Base.Applicative t) => Predicate.Core.P (Predicate.Core.Pure t p) x
+ Predicate.Core: instance forall k (p :: k) x s. (Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x, GHC.Show.Show s, GHC.Show.Show (Control.Lens.Wrapped.Unwrapped s), Control.Lens.Wrapped.Wrapped s) => Predicate.Core.P (Predicate.Core.Unwrap p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL1T (Predicate.Core.PP p x)), Predicate.Core.ExtractL1C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.Fst p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL2T (Predicate.Core.PP p x)), Predicate.Core.ExtractL2C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.Snd p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL3T (Predicate.Core.PP p x)), Predicate.Core.ExtractL3C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.Thd p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL4T (Predicate.Core.PP p x)), Predicate.Core.ExtractL4C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.L4 p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL5T (Predicate.Core.PP p x)), Predicate.Core.ExtractL5C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.L5 p) x
+ Predicate.Core: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.ExtractL6T (Predicate.Core.PP p x)), Predicate.Core.ExtractL6C (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Core.L6 p) x
+ Predicate.Core: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Core.IdBool p) x
+ Predicate.Core: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Core.Not p) x
+ Predicate.Core: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Core.Fail Predicate.Core.I p) x => Predicate.Core.P (Predicate.Core.FailS p) x
+ Predicate.Core: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Core.Fail Predicate.Core.Unproxy p) x => Predicate.Core.P (Predicate.Core.Failp p) x
+ Predicate.Core: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Core.L1T p) x => Predicate.Core.P (Predicate.Core.L1 p) x
+ Predicate.Core: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Core.L2T p) x => Predicate.Core.P (Predicate.Core.L2 p) x
+ Predicate.Core: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Core.L3T p) x => Predicate.Core.P (Predicate.Core.L3 p) x
+ Predicate.Core: instance forall k (ps :: [k]) a. Predicate.Core.P (Predicate.Core.DoExpandT ps) a => Predicate.Core.P (Predicate.Core.Do ps) a
+ Predicate.Core: instance forall k (t :: * -> *) (p :: k) x a. (Data.Foldable.Foldable t, Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Core.OneP p) x
+ Predicate.Core: instance forall k k1 (p :: k -> k1) (q :: k) a. Predicate.Core.P (p q) a => Predicate.Core.P (p Predicate.Core.$ q) a
+ Predicate.Core: instance forall k k1 (p :: k -> k1) (q :: k) a. Predicate.Core.P (p q) a => Predicate.Core.P (q Predicate.Core.& p) a
+ Predicate.Core: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Core.Fail (Predicate.Core.Hole t) p) x => Predicate.Core.P (Predicate.Core.Failt t p) x
+ Predicate.Core: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Core.WrapT t p) x => Predicate.Core.P (Predicate.Core.Wrap t p) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Core.BetweenT p q) x => Predicate.Core.P (p Predicate.Core.<..> q) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Core.LeftArrowsT p q) x => Predicate.Core.P (p Predicate.Core.<< q) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, GHC.Show.Show (f a), Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Core.Map p q) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Core.All p q) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1) x (f :: * -> *). (Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q x Data.Type.Equality.~ f a, Predicate.Core.P q x, GHC.Show.Show a, Data.Foldable.Foldable f) => Predicate.Core.P (Predicate.Core.Any p q) x
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP p a)), Predicate.Core.P p a, Predicate.Core.P q (Predicate.Core.PP p a)) => Predicate.Core.P (p Predicate.Core.>> q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q a)) => Predicate.Core.P '(p, q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Core.&& q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Core.&&~ q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Core.|| q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Core.||~ q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (p Predicate.Core.~> q) a
+ Predicate.Core: instance forall k1 k2 (p :: k2) x (s :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, Control.Lens.Wrapped.Unwrapped (Predicate.Core.PP s x) Data.Type.Equality.~ Predicate.Core.PP p x, Control.Lens.Wrapped.Wrapped (Predicate.Core.PP s x), GHC.Show.Show (Predicate.Core.PP s x)) => Predicate.Core.P (Predicate.Core.Wrap' s p) x
+ Predicate.Core: instance forall k1 k2 (prt :: k2) a (p :: k1). (Predicate.Core.P prt a, Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p a) => Predicate.Core.P (Predicate.Core.MsgI prt p) a
+ Predicate.Core: instance forall k1 k2 (prt :: k2) a (t :: k1). (Predicate.Core.P prt a, Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Core.Fail t prt) a
+ Predicate.Core: instance forall k1 k2 (q :: k2) x (p :: k1). (Predicate.Core.ExtractL1C (Predicate.Core.PP q x), Predicate.Core.ExtractL2C (Predicate.Core.PP q x), Predicate.Core.P p (Predicate.Core.ExtractL1T (Predicate.Core.PP q x)), Predicate.Core.P p (Predicate.Core.ExtractL2T (Predicate.Core.PP q x)), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Core.Both p q) x
+ Predicate.Core: instance forall k1 k2 k3 (p :: k3) x (r :: k2) (q :: k1). (GHC.Classes.Ord (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP r x Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP r x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Core.Between p q r) x
+ Predicate.Core: swapC :: SwapC p => p a b -> p b a
+ Predicate.Data.Char: data Char1 (s :: Symbol)
+ Predicate.Data.Char: data IsControl
+ Predicate.Data.Char: data IsControlAll
+ Predicate.Data.Char: data IsDigit
+ Predicate.Data.Char: data IsDigitAll
+ Predicate.Data.Char: data IsHexDigit
+ Predicate.Data.Char: data IsHexDigitAll
+ Predicate.Data.Char: data IsLatin1
+ Predicate.Data.Char: data IsLatin1All
+ Predicate.Data.Char: data IsLower
+ Predicate.Data.Char: data IsLowerAll
+ Predicate.Data.Char: data IsOctDigit
+ Predicate.Data.Char: data IsOctDigitAll
+ Predicate.Data.Char: data IsPunctuation
+ Predicate.Data.Char: data IsPunctuationAll
+ Predicate.Data.Char: data IsSeparator
+ Predicate.Data.Char: data IsSeparatorAll
+ Predicate.Data.Char: data IsSpace
+ Predicate.Data.Char: data IsSpaceAll
+ Predicate.Data.Char: data IsUpper
+ Predicate.Data.Char: data IsUpperAll
+ Predicate.Data.Char: data ToLower
+ Predicate.Data.Char: data ToTitle
+ Predicate.Data.Char: data ToUpper
+ Predicate.Data.Char: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Data.Char.ToLower a
+ Predicate.Data.Char: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Data.Char.ToTitle a
+ Predicate.Data.Char: instance (GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P Predicate.Data.Char.ToUpper a
+ Predicate.Data.Char: instance (GHC.TypeLits.KnownSymbol s, GHC.TypeLits.CmpSymbol s "" Data.Type.Equality.~ 'GHC.Types.GT) => Predicate.Core.P (Predicate.Data.Char.Char1 s) a
+ Predicate.Data.Char: instance (Predicate.Data.Char.GetCharSet cs, GHC.Show.Show a, Data.Text.Lens.IsText a) => Predicate.Core.P (Predicate.Data.Char.IsCharSetAll cs) a
+ Predicate.Data.Char: instance (x Data.Type.Equality.~ GHC.Types.Char, Predicate.Data.Char.GetCharSet cs) => Predicate.Core.P (Predicate.Data.Char.IsCharSet cs) x
+ Predicate.Data.Char: instance GHC.Show.Show Predicate.Data.Char.CharSet
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsControlAllT x => Predicate.Core.P Predicate.Data.Char.IsControlAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsControlT x => Predicate.Core.P Predicate.Data.Char.IsControl x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsDigitAllT x => Predicate.Core.P Predicate.Data.Char.IsDigitAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsDigitT x => Predicate.Core.P Predicate.Data.Char.IsDigit x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsHexDigitAllT x => Predicate.Core.P Predicate.Data.Char.IsHexDigitAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsHexDigitT x => Predicate.Core.P Predicate.Data.Char.IsHexDigit x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsLatin1AllT x => Predicate.Core.P Predicate.Data.Char.IsLatin1All x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsLatin1T x => Predicate.Core.P Predicate.Data.Char.IsLatin1 x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsLowerAllT x => Predicate.Core.P Predicate.Data.Char.IsLowerAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsLowerT x => Predicate.Core.P Predicate.Data.Char.IsLower x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsOctDigitAllT x => Predicate.Core.P Predicate.Data.Char.IsOctDigitAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsOctDigitT x => Predicate.Core.P Predicate.Data.Char.IsOctDigit x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsPunctuationAllT x => Predicate.Core.P Predicate.Data.Char.IsPunctuationAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsPunctuationT x => Predicate.Core.P Predicate.Data.Char.IsPunctuation x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsSeparatorAllT x => Predicate.Core.P Predicate.Data.Char.IsSeparatorAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsSeparatorT x => Predicate.Core.P Predicate.Data.Char.IsSeparator x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsSpaceAllT x => Predicate.Core.P Predicate.Data.Char.IsSpaceAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsSpaceT x => Predicate.Core.P Predicate.Data.Char.IsSpace x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsUpperAllT x => Predicate.Core.P Predicate.Data.Char.IsUpperAll x
+ Predicate.Data.Char: instance Predicate.Core.P Predicate.Data.Char.IsUpperT x => Predicate.Core.P Predicate.Data.Char.IsUpper x
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CControl
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CHexDigit
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CLatin1
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CLower
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CNumber
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.COctDigit
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CPunctuation
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CSeparator
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CSpace
+ Predicate.Data.Char: instance Predicate.Data.Char.GetCharSet 'Predicate.Data.Char.CUpper
+ Predicate.Data.Condition: data Bools (ps :: [(k, k1)])
+ Predicate.Data.Condition: data BoolsN prt (n :: Nat) (p :: k1)
+ Predicate.Data.Condition: data BoolsQuick (prt :: k) (ps :: [k1])
+ Predicate.Data.Condition: data Case (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
+ Predicate.Data.Condition: data Case' (ps :: [k]) (qs :: [k1]) (r :: k2)
+ Predicate.Data.Condition: data Case'' s (ps :: [k]) (qs :: [k1]) (r :: k2)
+ Predicate.Data.Condition: data ExitWhen prt p
+ Predicate.Data.Condition: data Guard prt p
+ Predicate.Data.Condition: data GuardSimple p
+ Predicate.Data.Condition: data Guards (ps :: [(k, k1)])
+ Predicate.Data.Condition: data GuardsDetail prt (ps :: [(k0, k1)])
+ Predicate.Data.Condition: data GuardsN prt (n :: Nat) p
+ Predicate.Data.Condition: data GuardsQuick (prt :: k) (ps :: [k1])
+ Predicate.Data.Condition: data If p q r
+ Predicate.Data.Condition: instance (GHC.TypeNats.KnownNat n, GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Data.Condition.BoolsImpl n '[]) x
+ Predicate.Data.Condition: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Condition.GuardsImpl n '[]) x
+ Predicate.Data.Condition: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Condition.GuardsImplX n '[]) x
+ Predicate.Data.Condition: instance forall k a (p :: k). (GHC.Show.Show a, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Condition.GuardSimple p) a
+ Predicate.Data.Condition: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Data.Condition.BoolsImpl (Predicate.Util.LenT ps) ps) x, Predicate.Core.PP (Predicate.Data.Condition.BoolsImpl (Predicate.Util.LenT ps) ps) x Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Condition.Bools ps) x
+ Predicate.Data.Condition: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Data.Condition.GuardsImpl (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Data.Condition.Guards ps) x
+ Predicate.Data.Condition: instance forall k k1 a x (ps :: [(k, k1)]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Data.Condition.GuardsImplX (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Data.Condition.GuardsDetailImpl ps) x
+ Predicate.Data.Condition: instance forall k0 k k1 k2 (r :: k2) x (q :: k1) (p :: k) (n :: GHC.Types.Nat) (e :: k0). (Predicate.Core.P r x, Predicate.Core.P q (Predicate.Core.PP r x), GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP r x)), Predicate.Core.P p (Predicate.Core.PP r x), Predicate.Core.PP p (Predicate.Core.PP r x) Data.Type.Equality.~ GHC.Types.Bool, GHC.TypeNats.KnownNat n, GHC.Show.Show (Predicate.Core.PP r x), Predicate.Core.P e (Predicate.Core.PP r x, Data.Proxy.Proxy (Predicate.Core.PP q (Predicate.Core.PP r x))), Predicate.Core.PP e (Predicate.Core.PP r x, Data.Proxy.Proxy (Predicate.Core.PP q (Predicate.Core.PP r x))) Data.Type.Equality.~ Predicate.Core.PP q (Predicate.Core.PP r x)) => Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e '[p] '[q] r) x
+ Predicate.Data.Condition: instance forall k0 k1 k (prt :: k) (ps :: [(k0, k1)]) x. Predicate.Core.P (Predicate.Data.Condition.GuardsDetailT prt ps) x => Predicate.Core.P (Predicate.Data.Condition.GuardsDetail prt ps) x
+ Predicate.Data.Condition: instance forall k0 k1 k2 k (n :: GHC.Types.Nat) (ps :: [k]) (r :: k2) x (p :: k) (q :: k1) (e :: k0) (p1 :: k) (q1 :: k1) (qs :: [k1]). (GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P r x, Predicate.Core.P p (Predicate.Core.PP r x), Predicate.Core.P q (Predicate.Core.PP r x), Predicate.Core.PP p (Predicate.Core.PP r x) Data.Type.Equality.~ GHC.Types.Bool, GHC.Show.Show (Predicate.Core.PP q (Predicate.Core.PP r x)), GHC.Show.Show (Predicate.Core.PP r x), Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e (p1 : ps) (q1 : qs) r) x, Predicate.Core.PP (Predicate.Data.Condition.CaseImpl n e (p1 : ps) (q1 : qs) r) x Data.Type.Equality.~ Predicate.Core.PP q (Predicate.Core.PP r x)) => Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e (p : p1 : ps) (q : q1 : qs) r) x
+ Predicate.Data.Condition: instance forall k1 k (prt :: k) (ps :: [k1]) x. (Predicate.Core.PP (Predicate.Data.Condition.Bools (Predicate.Data.Condition.ToGuardsT prt ps)) x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Data.Condition.BoolsQuickT prt ps) x) => Predicate.Core.P (Predicate.Data.Condition.BoolsQuick prt ps) x
+ Predicate.Data.Condition: instance forall k1 k (prt :: k) (ps :: [k1]) x. Predicate.Core.P (Predicate.Data.Condition.GuardsQuickT prt ps) x => Predicate.Core.P (Predicate.Data.Condition.GuardsQuick prt ps) x
+ Predicate.Data.Condition: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt (GHC.Types.Int, a) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt (GHC.Types.Int, a), GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Data.Condition.BoolsImpl n ps) x, Predicate.Core.PP (Predicate.Data.Condition.BoolsImpl n ps) [a] Data.Type.Equality.~ GHC.Types.Bool, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Data.Condition.BoolsImpl n ('(prt, p) : ps)) x
+ Predicate.Data.Condition: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt (GHC.Types.Int, a) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt (GHC.Types.Int, a), GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Data.Condition.GuardsImpl n ps) [a], Predicate.Core.PP (Predicate.Data.Condition.GuardsImpl n ps) [a] Data.Type.Equality.~ [a], GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Data.Condition.GuardsImpl n ('(prt, p) : ps)) x
+ Predicate.Data.Condition: instance forall k1 k (prt :: k) a (n :: GHC.Types.Nat) (ps :: [(k, k1)]) (p :: k1) x. (Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P prt a, GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P (Predicate.Data.Condition.GuardsImplX n ps) [a], Predicate.Core.PP (Predicate.Data.Condition.GuardsImplX n ps) [a] Data.Type.Equality.~ [a], GHC.Show.Show a, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Data.Condition.GuardsImplX n ('(prt, p) : ps)) x
+ Predicate.Data.Condition: instance forall k1 k x a (prt :: k) (n :: GHC.Types.Nat) (p :: k1). (x Data.Type.Equality.~ [a], Predicate.Core.P (Predicate.Data.Condition.BoolsNT prt n p) x) => Predicate.Core.P (Predicate.Data.Condition.BoolsN prt n p) x
+ Predicate.Data.Condition: instance forall k1 k2 (prt :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Data.Condition.ExitWhenT prt p) x => Predicate.Core.P (Predicate.Data.Condition.ExitWhen prt p) x
+ Predicate.Data.Condition: instance forall k1 k2 a (prt :: k2) (p :: k1). (GHC.Show.Show a, Predicate.Core.P prt a, Predicate.Core.PP prt a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Condition.Guard prt p) a
+ Predicate.Data.Condition: instance forall k1 k2 k3 (r :: k3) a (p :: k2) (q :: k1). (GHC.Show.Show (Predicate.Core.PP r a), Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a, Predicate.Core.P r a, Predicate.Core.PP q a Data.Type.Equality.~ Predicate.Core.PP r a) => Predicate.Core.P (Predicate.Data.Condition.If p q r) a
+ Predicate.Data.Condition: instance forall k1 k2 x a (prt :: k2) (n :: GHC.Types.Nat) (p :: k1). (x Data.Type.Equality.~ [a], Predicate.Core.P (Predicate.Data.Condition.GuardsNT prt n p) x) => Predicate.Core.P (Predicate.Data.Condition.GuardsN prt n p) x
+ Predicate.Data.Condition: instance forall k2 k k0 k1 (n :: GHC.Types.Nat) (e :: k0) (p :: k) (ps :: [k]) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e (p : ps) '[] r) x
+ Predicate.Data.Condition: instance forall k2 k0 k k1 (n :: GHC.Types.Nat) (e :: k0) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e '[] '[] r) x
+ Predicate.Data.Condition: instance forall k2 k0 k1 k (ps :: [k]) (qs :: [k1]) (e :: k0) (r :: k2) x. (Predicate.Util.FailUnlessT (Predicate.Util.LenT ps Data.Type.Equality.== Predicate.Util.LenT qs) ((('GHC.TypeLits.Text "lengths are not the same " 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType (Predicate.Util.LenT ps)) 'GHC.TypeLits.:<>: 'GHC.TypeLits.Text " vs ") 'GHC.TypeLits.:<>: 'GHC.TypeLits.ShowType (Predicate.Util.LenT qs)), Predicate.Core.P (Predicate.Data.Condition.CaseImplT e ps qs r) x) => Predicate.Core.P (Predicate.Data.Condition.Case e ps qs r) x
+ Predicate.Data.Condition: instance forall k2 k1 k (ps :: [k]) (qs :: [k1]) (r :: k2) x. Predicate.Core.P (Predicate.Data.Condition.CaseT' ps qs r) x => Predicate.Core.P (Predicate.Data.Condition.Case' ps qs r) x
+ Predicate.Data.Condition: instance forall k2 k1 k0 k (n :: GHC.Types.Nat) (e :: k0) (q :: k1) (qs :: [k1]) (r :: k2) x. (TypeError ...) => Predicate.Core.P (Predicate.Data.Condition.CaseImpl n e '[] (q : qs) r) x
+ Predicate.Data.Condition: instance forall k2 k1 k4 k5 (s :: k5) (ps :: [k4]) (qs :: [k1]) (r :: k2) x. Predicate.Core.P (Predicate.Data.Condition.CaseT'' s ps qs r) x => Predicate.Core.P (Predicate.Data.Condition.Case'' s ps qs r) x
+ Predicate.Data.DateTime: data FormatTimeP p q
+ Predicate.Data.DateTime: data MkDay p
+ Predicate.Data.DateTime: data MkDay' p q r
+ Predicate.Data.DateTime: data MkDayExtra p
+ Predicate.Data.DateTime: data MkDayExtra' p q r
+ Predicate.Data.DateTime: data MkTime p
+ Predicate.Data.DateTime: data MkTime' p q r
+ Predicate.Data.DateTime: data ParseTimeP (t :: Type) p q
+ Predicate.Data.DateTime: data ParseTimeP' t p q
+ Predicate.Data.DateTime: data ParseTimes (t :: Type) p q
+ Predicate.Data.DateTime: data ParseTimes' t p q
+ Predicate.Data.DateTime: data PosixToUTCTime p
+ Predicate.Data.DateTime: data ToDay p
+ Predicate.Data.DateTime: data ToTime p
+ Predicate.Data.DateTime: data ToWeekDate p
+ Predicate.Data.DateTime: data ToWeekYear p
+ Predicate.Data.DateTime: data UTCTimeToPosix p
+ Predicate.Data.DateTime: data UnMkDay p
+ Predicate.Data.DateTime: data UnMkTime p
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC Data.Time.Calendar.Days.Day
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC Data.Time.Clock.Internal.SystemTime.SystemTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC Data.Time.Clock.Internal.UTCTime.UTCTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC Data.Time.LocalTime.Internal.LocalTime.LocalTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToDayC GHC.Real.Rational
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.Clock.Internal.DiffTime.DiffTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.Clock.Internal.SystemTime.SystemTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.Clock.Internal.UTCTime.UTCTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.LocalTime.Internal.LocalTime.LocalTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC Data.Time.LocalTime.Internal.ZonedTime.ZonedTime
+ Predicate.Data.DateTime: instance Predicate.Data.DateTime.ToTimeC GHC.Real.Rational
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Data.DateTime.ToDayC (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Data.DateTime.ToDay p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Data.DateTime.ToTimeC (Predicate.Core.PP p x)) => Predicate.Core.P (Predicate.Data.DateTime.ToTime p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day) => Predicate.Core.P (Predicate.Data.DateTime.ToWeekDate p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day) => Predicate.Core.P (Predicate.Data.DateTime.ToWeekYear p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Calendar.Days.Day, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.DateTime.UnMkDay p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.Clock.Internal.UTCTime.UTCTime, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.DateTime.UTCTimeToPosix p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.DateTime.UnMkTime p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Real.Rational, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.DateTime.PosixToUTCTime p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.DateTime.MkDayExtraT p) x => Predicate.Core.P (Predicate.Data.DateTime.MkDayExtra p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.DateTime.MkDayT p) x => Predicate.Core.P (Predicate.Data.DateTime.MkDay p) x
+ Predicate.Data.DateTime: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.DateTime.MkTimeT p) x => Predicate.Core.P (Predicate.Data.DateTime.MkTime p) x
+ Predicate.Data.DateTime: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Time.Format.FormatTime (Predicate.Core.PP q x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.DateTime.FormatTimeP p q) x
+ Predicate.Data.DateTime: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Real.Rational) => Predicate.Core.P (Predicate.Data.DateTime.MkTime' p q r) x
+ Predicate.Data.DateTime: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Types.Int) => Predicate.Core.P (Predicate.Data.DateTime.MkDay' p q r) x
+ Predicate.Data.DateTime: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Types.Int, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Types.Int) => Predicate.Core.P (Predicate.Data.DateTime.MkDayExtra' p q r) x
+ Predicate.Data.DateTime: instance forall k1 k2 k3 (t :: k3) a (p :: k2) (q :: k1). (Data.Time.Format.Parse.ParseTime (Predicate.Core.PP t a), Data.Typeable.Internal.Typeable (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP t a), Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Data.DateTime.ParseTimeP' t p q) a
+ Predicate.Data.DateTime: instance forall k1 k2 k3 (t :: k3) a (p :: k2) (q :: k1). (Data.Time.Format.Parse.ParseTime (Predicate.Core.PP t a), Data.Typeable.Internal.Typeable (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP t a), Predicate.Core.P p a, Predicate.Core.P q a, Predicate.Core.PP p a Data.Type.Equality.~ [GHC.Base.String], Predicate.Core.PP q a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Data.DateTime.ParseTimes' t p q) a
+ Predicate.Data.DateTime: instance forall k1 k2 t (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.DateTime.ParseTimePT t p q) x => Predicate.Core.P (Predicate.Data.DateTime.ParseTimeP t p q) x
+ Predicate.Data.DateTime: instance forall k1 k2 t (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.DateTime.ParseTimesT t p q) x => Predicate.Core.P (Predicate.Data.DateTime.ParseTimes t p q) x
+ Predicate.Data.Either: data EitherBool b p q
+ Predicate.Data.Either: data IsLeft p
+ Predicate.Data.Either: data IsRight p
+ Predicate.Data.Either: data Left'
+ Predicate.Data.Either: data LeftDef p q
+ Predicate.Data.Either: data LeftFail p q
+ Predicate.Data.Either: data MkLeft (t :: Type) p
+ Predicate.Data.Either: data MkLeft' t p
+ Predicate.Data.Either: data MkRight (t :: Type) p
+ Predicate.Data.Either: data MkRight' t p
+ Predicate.Data.Either: data PartitionEithers
+ Predicate.Data.Either: data Right'
+ Predicate.Data.Either: data RightDef p q
+ Predicate.Data.Either: data RightFail p q
+ Predicate.Data.Either: data p +++ q
+ Predicate.Data.Either: infixr 2 +++
+ Predicate.Data.Either: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Data.Either.PartitionEithers [Data.Either.Either a b]
+ Predicate.Data.Either: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.Either.Left' (Data.Either.Either a x)
+ Predicate.Data.Either: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.Either.Right' (Data.Either.Either x a)
+ Predicate.Data.Either: instance forall k (p :: k) x a b. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a b) => Predicate.Core.P (Predicate.Data.Either.IsLeft p) x
+ Predicate.Data.Either: instance forall k (p :: k) x a b. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.Either.Either a b) => Predicate.Core.P (Predicate.Data.Either.IsRight p) x
+ Predicate.Data.Either: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Either.MkLeftT t p) x => Predicate.Core.P (Predicate.Data.Either.MkLeft t p) x
+ Predicate.Data.Either: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Either.MkRightT t p) x => Predicate.Core.P (Predicate.Data.Either.MkRight t p) x
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q b), Predicate.Core.P p a, Predicate.Core.P q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Data.Either.+++ q) (Data.Either.Either a b)
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Data.Either.||| q) (Data.Either.Either a b)
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) a x (q :: k1) b. (Predicate.Core.PP p (a, x) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.P p (a, x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Either.RightFail p q) x
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) b x (q :: k1) a. (Predicate.Core.PP p (b, x) Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.P p (b, x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Either.LeftFail p q) x
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Either.MkLeft' t p) x
+ Predicate.Data.Either: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Either.MkRight' t p) x
+ Predicate.Data.Either: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (a, x) Data.Type.Equality.~ b, Predicate.Core.P q x, Predicate.Core.P p (a, x)) => Predicate.Core.P (Predicate.Data.Either.RightDef p q) x
+ Predicate.Data.Either: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (b, x) Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (b, x)) => Predicate.Core.P (Predicate.Data.Either.LeftDef p q) x
+ Predicate.Data.Either: instance forall k1 k2 k3 (p :: k3) a (q :: k2) (b :: k1). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.P q a, Predicate.Core.P b a, Predicate.Core.PP b a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Either.EitherBool b p q) a
+ Predicate.Data.Either: instance forall k1 k2 k3 (r :: k3) x (p :: k2) a (q :: k1) b c. (Predicate.Core.P r x, Predicate.Core.P p (x, a), Predicate.Core.P q (x, b), Predicate.Core.PP r x Data.Type.Equality.~ Data.Either.Either a b, Predicate.Core.PP p (x, a) Data.Type.Equality.~ c, Predicate.Core.PP q (x, b) Data.Type.Equality.~ c) => Predicate.Core.P (Predicate.Data.Either.EitherX p q r) x
+ Predicate.Data.Either: type EitherIn p q = p ||| q
+ Predicate.Data.Enum: data EnumFromThenTo p q r
+ Predicate.Data.Enum: data EnumFromTo p q
+ Predicate.Data.Enum: data FromEnum p
+ Predicate.Data.Enum: data Pred p
+ Predicate.Data.Enum: data PredB p q
+ Predicate.Data.Enum: data PredB' q
+ Predicate.Data.Enum: data Succ p
+ Predicate.Data.Enum: data SuccB p q
+ Predicate.Data.Enum: data SuccB' q
+ Predicate.Data.Enum: data SuccN n p
+ Predicate.Data.Enum: data ToEnum (t :: Type) p
+ Predicate.Data.Enum: data ToEnum' t p
+ Predicate.Data.Enum: data ToEnumBDef (t :: Type) def
+ Predicate.Data.Enum: data ToEnumBDef' t def
+ Predicate.Data.Enum: data ToEnumBFail (t :: Type)
+ Predicate.Data.Enum: data p ... q
+ Predicate.Data.Enum: infix 4 ...
+ Predicate.Data.Enum: instance Predicate.Core.P (Predicate.Data.Enum.ToEnumBFailT t) x => Predicate.Core.P (Predicate.Data.Enum.ToEnumBFail t) x
+ Predicate.Data.Enum: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Data.Enum.PredBT' q) x => Predicate.Core.P (Predicate.Data.Enum.PredB' q) x
+ Predicate.Data.Enum: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Data.Enum.SuccBT' q) x => Predicate.Core.P (Predicate.Data.Enum.SuccB' q) x
+ Predicate.Data.Enum: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Enum.FromEnum p) x
+ Predicate.Data.Enum: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Enum.Pred p) x
+ Predicate.Data.Enum: instance forall k a (p :: k) x. (GHC.Show.Show a, GHC.Enum.Enum a, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Enum.Succ p) x
+ Predicate.Data.Enum: instance forall k t (def :: k) x. Predicate.Core.P (Predicate.Data.Enum.ToEnumBDefT t def) x => Predicate.Core.P (Predicate.Data.Enum.ToEnumBDef t def) x
+ Predicate.Data.Enum: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Enum.ToEnumT t p) x => Predicate.Core.P (Predicate.Data.Enum.ToEnum t p) x
+ Predicate.Data.Enum: instance forall k1 k2 (def :: k2) (t :: k1) a. (Predicate.Core.P def (Data.Proxy.Proxy (Predicate.Core.PP t a)), Predicate.Core.PP def (Data.Proxy.Proxy (Predicate.Core.PP t a)) Data.Type.Equality.~ Predicate.Core.PP t a, GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Enum.Bounded (Predicate.Core.PP t a), GHC.Enum.Enum (Predicate.Core.PP t a), GHC.Real.Integral a) => Predicate.Core.P (Predicate.Data.Enum.ToEnumBDef' t def) a
+ Predicate.Data.Enum: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Enum.EnumFromToT p q) x => Predicate.Core.P (p Predicate.Data.Enum.... q) x
+ Predicate.Data.Enum: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Data.Enum.EnumFromTo p q) x
+ Predicate.Data.Enum: instance forall k1 k2 (p :: k2) x a (t :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Enum.Enum (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.Integral a) => Predicate.Core.P (Predicate.Data.Enum.ToEnum' t p) x
+ Predicate.Data.Enum: instance forall k1 k2 (q :: k2) x a (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (Data.Proxy.Proxy a), Predicate.Core.PP p (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Classes.Eq a, GHC.Enum.Bounded a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Data.Enum.PredB p q) x
+ Predicate.Data.Enum: instance forall k1 k2 (q :: k2) x a (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p (Data.Proxy.Proxy a), Predicate.Core.PP p (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Classes.Eq a, GHC.Enum.Bounded a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Data.Enum.SuccB p q) x
+ Predicate.Data.Enum: instance forall k1 k2 a (n :: k2) x (p :: k1). (GHC.Show.Show a, GHC.Enum.Enum a, GHC.Real.Integral (Predicate.Core.PP n x), Predicate.Core.P n x, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Enum.SuccN n p) x
+ Predicate.Data.Enum: instance forall k1 k2 k3 (p :: k3) x (q :: k2) (r :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ a, Predicate.Core.PP r x Data.Type.Equality.~ a, GHC.Enum.Enum a) => Predicate.Core.P (Predicate.Data.Enum.EnumFromThenTo p q r) x
+ Predicate.Data.Extra: data Catch p q
+ Predicate.Data.Extra: data Catch' p s
+ Predicate.Data.Extra: data Coerce2 (t :: k)
+ Predicate.Data.Extra: data Dot (ps :: [Type -> Type]) (q :: Type)
+ Predicate.Data.Extra: data Duplicate
+ Predicate.Data.Extra: data Extract
+ Predicate.Data.Extra: data FMapFst
+ Predicate.Data.Extra: data FMapSnd
+ Predicate.Data.Extra: data HeadDef p q
+ Predicate.Data.Extra: data HeadFail msg q
+ Predicate.Data.Extra: data InitDef p q
+ Predicate.Data.Extra: data InitFail msg q
+ Predicate.Data.Extra: data Join
+ Predicate.Data.Extra: data K (p :: k) (q :: k1)
+ Predicate.Data.Extra: data LastDef p q
+ Predicate.Data.Extra: data LastFail msg q
+ Predicate.Data.Extra: data Luhn p
+ Predicate.Data.Extra: data Prime p
+ Predicate.Data.Extra: data PrimeNext p
+ Predicate.Data.Extra: data ProxyT (t :: Type)
+ Predicate.Data.Extra: data ProxyT' t
+ Predicate.Data.Extra: data Pure2 (t :: Type -> Type)
+ Predicate.Data.Extra: data RDot (ps :: [Type -> Type]) (q :: Type)
+ Predicate.Data.Extra: data Sequence
+ Predicate.Data.Extra: data Skip p
+ Predicate.Data.Extra: data TailDef p q
+ Predicate.Data.Extra: data TailFail msg q
+ Predicate.Data.Extra: data Traverse p q
+ Predicate.Data.Extra: data p >|> q
+ Predicate.Data.Extra: data q $& p
+ Predicate.Data.Extra: infixl 0 $$
+ Predicate.Data.Extra: infixl 3 <|>
+ Predicate.Data.Extra: infixl 4 *>
+ Predicate.Data.Extra: infixr 1 >|>
+ Predicate.Data.Extra: instance (GHC.Show.Show (f (t a)), GHC.Show.Show (f a), GHC.Base.Applicative t, GHC.Base.Functor f) => Predicate.Core.P (Predicate.Data.Extra.Pure2 t) (f a)
+ Predicate.Data.Extra: instance (GHC.Show.Show (f (t a)), GHC.Show.Show (t (f a)), Data.Traversable.Traversable t, GHC.Base.Applicative f) => Predicate.Core.P Predicate.Data.Extra.Sequence (t (f a))
+ Predicate.Data.Extra: instance (GHC.Show.Show (f a), GHC.Show.Show (f t), GHC.Types.Coercible t a, GHC.Base.Functor f) => Predicate.Core.P (Predicate.Data.Extra.Coerce2 t) (f a)
+ Predicate.Data.Extra: instance (GHC.Show.Show (t (t a)), GHC.Show.Show (t a), GHC.Base.Monad t) => Predicate.Core.P Predicate.Data.Extra.Join (t (t a))
+ Predicate.Data.Extra: instance (GHC.Show.Show (t a), GHC.Show.Show (t (t a)), Control.Comonad.Comonad t) => Predicate.Core.P Predicate.Data.Extra.Duplicate (t a)
+ Predicate.Data.Extra: instance (GHC.Show.Show (t a), GHC.Show.Show a, Control.Comonad.Comonad t) => Predicate.Core.P Predicate.Data.Extra.Extract (t a)
+ Predicate.Data.Extra: instance GHC.Base.Functor f => Predicate.Core.P Predicate.Data.Extra.FMapFst (f (a, x))
+ Predicate.Data.Extra: instance GHC.Base.Functor f => Predicate.Core.P Predicate.Data.Extra.FMapSnd (f (x, a))
+ Predicate.Data.Extra: instance Predicate.Core.P (Predicate.Data.Extra.DotExpandT ps q) a => Predicate.Core.P (Predicate.Data.Extra.Dot ps q) a
+ Predicate.Data.Extra: instance Predicate.Core.P (Predicate.Data.Extra.ProxyT t) x
+ Predicate.Data.Extra: instance Predicate.Core.P (Predicate.Data.Extra.RDotExpandT ps q) a => Predicate.Core.P (Predicate.Data.Extra.RDot ps q) a
+ Predicate.Data.Extra: instance forall k (p :: k) a. (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a) => Predicate.Core.P (Predicate.Data.Extra.Skip p) a
+ Predicate.Data.Extra: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Data.Extra.Prime p) x
+ Predicate.Data.Extra: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Data.Extra.PrimeNext p) x
+ Predicate.Data.Extra: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ [GHC.Types.Int], Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Extra.Luhn p) x
+ Predicate.Data.Extra: instance forall k (t :: k) x. Predicate.Core.P (Predicate.Data.Extra.ProxyT' t) x
+ Predicate.Data.Extra: instance forall k1 k (p :: k) a (q :: k1). Predicate.Core.P p a => Predicate.Core.P (Predicate.Data.Extra.K p q) a
+ Predicate.Data.Extra: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.HeadFailT msg q) x => Predicate.Core.P (Predicate.Data.Extra.HeadFail msg q) x
+ Predicate.Data.Extra: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.InitFailT msg q) x => Predicate.Core.P (Predicate.Data.Extra.InitFail msg q) x
+ Predicate.Data.Extra: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.LastFailT msg q) x => Predicate.Core.P (Predicate.Data.Extra.LastFail msg q) x
+ Predicate.Data.Extra: instance forall k1 k2 (msg :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.TailFailT msg q) x => Predicate.Core.P (Predicate.Data.Extra.TailFail msg q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.ArrowRT p q) x => Predicate.Core.P (p Predicate.Data.Extra.*> q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.HeadDefT p q) x => Predicate.Core.P (Predicate.Data.Extra.HeadDef p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.InitDefT p q) x => Predicate.Core.P (Predicate.Data.Extra.InitDef p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.LastDefT p q) x => Predicate.Core.P (Predicate.Data.Extra.LastDef p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.SkipBothT p q) x => Predicate.Core.P (p Predicate.Data.Extra.>|> q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.SkipLT p q) x => Predicate.Core.P (p Predicate.Data.Extra.|> q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.SkipRT p q) x => Predicate.Core.P (p Predicate.Data.Extra.>| q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.TailDefT p q) x => Predicate.Core.P (Predicate.Data.Extra.TailDef p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Extra.TraverseT p q) x => Predicate.Core.P (Predicate.Data.Extra.Traverse p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) (s :: k1) x. Predicate.Core.P (Predicate.Data.Extra.CatchT' p s) x => Predicate.Core.P (Predicate.Data.Extra.Catch' p s) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) x (q :: k1) (t :: * -> *) b. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (t b), GHC.Base.Alternative t, t b Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP q x Data.Type.Equality.~ t b) => Predicate.Core.P (p Predicate.Data.Extra.<|> q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) x (q :: k1) (t :: * -> *) c. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Base.Functor t, Predicate.Core.PP q x Data.Type.Equality.~ t c, Predicate.Data.Extra.ApplyConstT (Predicate.Core.PP q x) (Predicate.Core.PP p x) Data.Type.Equality.~ t (Predicate.Core.PP p x)) => Predicate.Core.P (p Predicate.Data.Extra.<$ q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ (a -> b), Predicate.Data.Extra.FnT (Predicate.Core.PP p x) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Data.Extra.$$ q) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ (a -> b), Predicate.Data.Extra.FnT (Predicate.Core.PP p x) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ a, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (q Predicate.Data.Extra.$& p) x
+ Predicate.Data.Extra: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q ((GHC.Base.String, x), Data.Proxy.Proxy (Predicate.Core.PP p x)), Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q ((GHC.Base.String, x), Data.Proxy.Proxy (Predicate.Core.PP p x))) => Predicate.Core.P (Predicate.Data.Extra.Catch p q) x
+ Predicate.Data.Extra: instance forall k1 k2 (t :: * -> *) c (p :: k2) x (q :: k1) b. (GHC.Show.Show (t c), Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (t b), GHC.Base.Applicative t, t b Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.PP q x Data.Type.Equality.~ t c) => Predicate.Core.P (p Predicate.Data.Extra.<* q) x
+ Predicate.Data.Foldable: data Concat p
+ Predicate.Data.Foldable: data ConcatMap p q
+ Predicate.Data.Foldable: data Cycle n p
+ Predicate.Data.Foldable: data FoldMap (t :: Type) p
+ Predicate.Data.Foldable: data FromList (t :: Type)
+ Predicate.Data.Foldable: data FromListExt (t :: Type)
+ Predicate.Data.Foldable: data IToList (t :: Type) p
+ Predicate.Data.Foldable: data IToList' t p
+ Predicate.Data.Foldable: data IsEmpty
+ Predicate.Data.Foldable: data Null
+ Predicate.Data.Foldable: data Null' p
+ Predicate.Data.Foldable: data ToList
+ Predicate.Data.Foldable: data ToList' p
+ Predicate.Data.Foldable: data ToListExt
+ Predicate.Data.Foldable: data ToNEList
+ Predicate.Data.Foldable: instance (GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P Predicate.Data.Foldable.ToList (t a)
+ Predicate.Data.Foldable: instance (GHC.Show.Show (t a), Data.Foldable.Foldable t) => Predicate.Core.P Predicate.Data.Foldable.ToNEList (t a)
+ Predicate.Data.Foldable: instance (GHC.Show.Show as, Control.Lens.Empty.AsEmpty as) => Predicate.Core.P Predicate.Data.Foldable.IsEmpty as
+ Predicate.Data.Foldable: instance (GHC.Show.Show l, GHC.Exts.IsList l, GHC.Show.Show (GHC.Exts.Item l)) => Predicate.Core.P Predicate.Data.Foldable.ToListExt l
+ Predicate.Data.Foldable: instance (GHC.Show.Show l, GHC.Exts.IsList l, l Data.Type.Equality.~ l') => Predicate.Core.P (Predicate.Data.Foldable.FromListExt l') l
+ Predicate.Data.Foldable: instance (a Data.Type.Equality.~ GHC.Exts.Item t, GHC.Show.Show t, GHC.Exts.IsList t, [a] Data.Type.Equality.~ x) => Predicate.Core.P (Predicate.Data.Foldable.FromList t) x
+ Predicate.Data.Foldable: instance Predicate.Core.P Predicate.Data.Foldable.NullT a => Predicate.Core.P Predicate.Data.Foldable.Null a
+ Predicate.Data.Foldable: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Foldable.ToList' p) x
+ Predicate.Data.Foldable: instance forall k (t :: * -> *) a (p :: k) x. (GHC.Show.Show (t a), Data.Foldable.Foldable t, t a Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Foldable.Null' p) x
+ Predicate.Data.Foldable: instance forall k a (t :: * -> *) (p :: k) x. (GHC.Show.Show a, GHC.Show.Show (t [a]), Predicate.Core.PP p x Data.Type.Equality.~ t [a], Predicate.Core.P p x, Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Data.Foldable.Concat p) x
+ Predicate.Data.Foldable: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Foldable.FoldMapT t p) x => Predicate.Core.P (Predicate.Data.Foldable.FoldMap t p) x
+ Predicate.Data.Foldable: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Foldable.IToListT t p) x => Predicate.Core.P (Predicate.Data.Foldable.IToList t p) x
+ Predicate.Data.Foldable: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Foldable.ConcatMapT p q) x => Predicate.Core.P (Predicate.Data.Foldable.ConcatMap p q) x
+ Predicate.Data.Foldable: instance forall k1 k2 a (t :: * -> *) (p :: k2) x (n :: k1). (GHC.Show.Show a, GHC.Show.Show (t a), Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Real.Integral (Predicate.Core.PP n x), Predicate.Core.P n x, Data.Foldable.Foldable t) => Predicate.Core.P (Predicate.Data.Foldable.Cycle n p) x
+ Predicate.Data.Foldable: instance forall k1 k2 x (p :: k2) (t :: k1) (f :: * -> *) a. (GHC.Show.Show x, Predicate.Core.P p x, Data.Typeable.Internal.Typeable (Predicate.Core.PP t (Predicate.Core.PP p x)), GHC.Show.Show (Predicate.Core.PP t (Predicate.Core.PP p x)), Control.Lens.Indexed.FoldableWithIndex (Predicate.Core.PP t (Predicate.Core.PP p x)) f, Predicate.Core.PP p x Data.Type.Equality.~ f a, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Foldable.IToList' t p) x
+ Predicate.Data.IO: data AppendFile (s :: Symbol) p
+ Predicate.Data.IO: data DirExists p
+ Predicate.Data.IO: data FileExists p
+ Predicate.Data.IO: data ReadDir p
+ Predicate.Data.IO: data ReadEnv p
+ Predicate.Data.IO: data ReadEnvAll
+ Predicate.Data.IO: data ReadFile p
+ Predicate.Data.IO: data Stderr p
+ Predicate.Data.IO: data Stdin
+ Predicate.Data.IO: data Stdout p
+ Predicate.Data.IO: data TimeUtc
+ Predicate.Data.IO: data TimeZt
+ Predicate.Data.IO: data WriteFile (s :: Symbol) p
+ Predicate.Data.IO: data WriteFile' (s :: Symbol) p
+ Predicate.Data.IO: instance (Predicate.Data.IO.GetMode w, GHC.TypeLits.KnownSymbol s) => Predicate.Data.IO.GetFHandle ('Predicate.Data.IO.FOther s w)
+ Predicate.Data.IO: instance GHC.Classes.Eq Predicate.Data.IO.WFMode
+ Predicate.Data.IO: instance GHC.Show.Show Predicate.Data.IO.WFMode
+ Predicate.Data.IO: instance GHC.Show.Show s => GHC.Show.Show (Predicate.Data.IO.FHandle s)
+ Predicate.Data.IO: instance Predicate.Core.P Predicate.Data.IO.ReadEnvAll a
+ Predicate.Data.IO: instance Predicate.Core.P Predicate.Data.IO.Stdin x
+ Predicate.Data.IO: instance Predicate.Core.P Predicate.Data.IO.TimeUtc a
+ Predicate.Data.IO: instance Predicate.Core.P Predicate.Data.IO.TimeZt a
+ Predicate.Data.IO: instance Predicate.Data.IO.GetFHandle 'Predicate.Data.IO.FStderr
+ Predicate.Data.IO: instance Predicate.Data.IO.GetFHandle 'Predicate.Data.IO.FStdout
+ Predicate.Data.IO: instance Predicate.Data.IO.GetMode 'Predicate.Data.IO.WFAppend
+ Predicate.Data.IO: instance Predicate.Data.IO.GetMode 'Predicate.Data.IO.WFWrite
+ Predicate.Data.IO: instance Predicate.Data.IO.GetMode 'Predicate.Data.IO.WFWriteForce
+ Predicate.Data.IO: instance forall k (fh :: Predicate.Data.IO.FHandle GHC.Types.Symbol) (p :: k) a. (Predicate.Data.IO.GetFHandle fh, Predicate.Core.P p a, Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String) => Predicate.Core.P (Predicate.Data.IO.WriteFileImpl fh p) a
+ Predicate.Data.IO: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.IO.ReadDir p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.IO.ReadEnv p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.IO.ReadFile p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.IO.DirExistsT p) x => Predicate.Core.P (Predicate.Data.IO.DirExists p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.IO.FileExistsT p) x => Predicate.Core.P (Predicate.Data.IO.FileExists p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.IO.StderrT p) x => Predicate.Core.P (Predicate.Data.IO.Stderr p) x
+ Predicate.Data.IO: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.IO.StdoutT p) x => Predicate.Core.P (Predicate.Data.IO.Stdout p) x
+ Predicate.Data.IO: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Data.IO.AppendFileT s p) x => Predicate.Core.P (Predicate.Data.IO.AppendFile s p) x
+ Predicate.Data.IO: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Data.IO.WriteFileT s p) x => Predicate.Core.P (Predicate.Data.IO.WriteFile s p) x
+ Predicate.Data.IO: instance forall k (s :: GHC.Types.Symbol) (p :: k) x. Predicate.Core.P (Predicate.Data.IO.WriteFileT' s p) x => Predicate.Core.P (Predicate.Data.IO.WriteFile' s p) x
+ Predicate.Data.IO: type ReadIO (t :: Type) = ReadIO' t "Enter value"
+ Predicate.Data.IO: type ReadIO' (t :: Type) s = Stdout (s <> ":") >> Stdin >> ReadP t Id
+ Predicate.Data.Index: data Ix (n :: Nat) def
+ Predicate.Data.Index: data Ix' (n :: Nat)
+ Predicate.Data.Index: data IxL p q def
+ Predicate.Data.Index: data Lookup p q
+ Predicate.Data.Index: data LookupDef v w p
+ Predicate.Data.Index: data LookupDef' v w p q
+ Predicate.Data.Index: data LookupFail msg v w
+ Predicate.Data.Index: data LookupFail' msg v w q
+ Predicate.Data.Index: data p !!? q
+ Predicate.Data.Index: instance Predicate.Core.P (Predicate.Data.Index.IxT' n) x => Predicate.Core.P (Predicate.Data.Index.Ix' n) x
+ Predicate.Data.Index: instance forall k (def :: k) a (n :: GHC.Types.Nat). (Predicate.Core.P def (Data.Proxy.Proxy a), Predicate.Core.PP def (Data.Proxy.Proxy a) Data.Type.Equality.~ a, GHC.TypeNats.KnownNat n, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Index.Ix n def) [a]
+ Predicate.Data.Index: instance forall k1 k2 (p :: k2) (q :: k1) a. Predicate.Core.P (Predicate.Data.Index.BangBangQT p q) a => Predicate.Core.P (p Predicate.Data.Index.!!? q) a
+ Predicate.Data.Index: instance forall k1 k2 (p :: k2) (q :: k1) a. Predicate.Core.P (Predicate.Data.Index.BangBangT p q) a => Predicate.Core.P (p Predicate.Data.Index.!! q) a
+ Predicate.Data.Index: instance forall k1 k2 (q :: k2) a (p :: k1). (Predicate.Core.P q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a), Control.Lens.At.Ixed (Predicate.Core.PP p a), Predicate.Core.PP q a Data.Type.Equality.~ Control.Lens.At.Index (Predicate.Core.PP p a), GHC.Show.Show (Control.Lens.At.Index (Predicate.Core.PP p a)), GHC.Show.Show (Control.Lens.At.IxValue (Predicate.Core.PP p a))) => Predicate.Core.P (Predicate.Data.Index.Lookup p q) a
+ Predicate.Data.Index: instance forall k1 k2 k3 (msg :: k3) (v :: k2) (w :: k1) x. Predicate.Core.P (Predicate.Data.Index.LookupFailT msg v w) x => Predicate.Core.P (Predicate.Data.Index.LookupFail msg v w) x
+ Predicate.Data.Index: instance forall k1 k2 k3 (q :: k3) a (p :: k2) (r :: k1). (Predicate.Core.P q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a), Control.Lens.At.Ixed (Predicate.Core.PP p a), Predicate.Core.PP q a Data.Type.Equality.~ Control.Lens.At.Index (Predicate.Core.PP p a), GHC.Show.Show (Control.Lens.At.Index (Predicate.Core.PP p a)), GHC.Show.Show (Control.Lens.At.IxValue (Predicate.Core.PP p a)), Predicate.Core.P r (Data.Proxy.Proxy (Control.Lens.At.IxValue (Predicate.Core.PP p a))), Predicate.Core.PP r (Data.Proxy.Proxy (Control.Lens.At.IxValue (Predicate.Core.PP p a))) Data.Type.Equality.~ Control.Lens.At.IxValue (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Index.IxL p q r) a
+ Predicate.Data.Index: instance forall k1 k2 k3 (v :: k3) (w :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Data.Index.LookupDefT v w p) x => Predicate.Core.P (Predicate.Data.Index.LookupDef v w p) x
+ Predicate.Data.Index: instance forall k1 k2 k3 k4 (msg :: k4) (v :: k3) (w :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Index.LookupFailT' msg v w q) x => Predicate.Core.P (Predicate.Data.Index.LookupFail' msg v w q) x
+ Predicate.Data.Index: instance forall k1 k2 k3 k4 (v :: k4) (w :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Index.LookupDefT' v w p q) x => Predicate.Core.P (Predicate.Data.Index.LookupDef' v w p q) x
+ Predicate.Data.Index: type Tuple2 p = '(p !! 0, p !! 1)
+ Predicate.Data.Index: type Tuple3 p = '(p !! 0, p !! 1, p !! 2)
+ Predicate.Data.Index: type Tuple4 p = '(p !! 0, p !! 1, p !! 2, p !! 3)
+ Predicate.Data.Index: type Tuple5 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4)
+ Predicate.Data.Index: type Tuple6 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4, p !! 5)
+ Predicate.Data.Iterator: data DoN (n :: Nat) p
+ Predicate.Data.Iterator: data FoldN n p q
+ Predicate.Data.Iterator: data Foldl p q r
+ Predicate.Data.Iterator: data IterateNUntil n p f
+ Predicate.Data.Iterator: data IterateNWhile n p f
+ Predicate.Data.Iterator: data IterateUntil p f
+ Predicate.Data.Iterator: data IterateWhile p f
+ Predicate.Data.Iterator: data Para (ps :: [k])
+ Predicate.Data.Iterator: data ParaN (n :: Nat) p
+ Predicate.Data.Iterator: data Repeat (n :: Nat) p
+ Predicate.Data.Iterator: data ScanN n p q
+ Predicate.Data.Iterator: data ScanNA q
+ Predicate.Data.Iterator: data Scanl p q r
+ Predicate.Data.Iterator: data Unfoldr p q
+ Predicate.Data.Iterator: instance (TypeError ...) => Predicate.Core.P (Predicate.Data.Iterator.ParaImpl n '[]) x
+ Predicate.Data.Iterator: instance forall k (n :: GHC.Types.Nat) (p :: k) a. Predicate.Core.P (Predicate.Data.Iterator.DoNT n p) a => Predicate.Core.P (Predicate.Data.Iterator.DoN n p) a
+ Predicate.Data.Iterator: instance forall k (n :: GHC.Types.Nat) (p :: k) a. Predicate.Core.P (Predicate.Util.RepeatT n p) a => Predicate.Core.P (Predicate.Data.Iterator.Repeat n p) a
+ Predicate.Data.Iterator: instance forall k (n :: GHC.Types.Nat) (p :: k) x a. (Predicate.Core.P (Predicate.Data.Iterator.ParaImpl (Predicate.Util.LenT (Predicate.Util.RepeatT n p)) (Predicate.Util.RepeatT n p)) x, Predicate.Util.GetLen (Predicate.Util.RepeatT n p), x Data.Type.Equality.~ [a]) => Predicate.Core.P (Predicate.Data.Iterator.ParaN n p) x
+ Predicate.Data.Iterator: instance forall k (n :: GHC.Types.Nat) (ps :: [k]) (p :: k) a (p1 :: k). (GHC.TypeNats.KnownNat n, Predicate.Util.GetLen ps, Predicate.Core.P p a, Predicate.Core.P (Predicate.Data.Iterator.ParaImpl n (p1 : ps)) [a], Predicate.Core.PP (Predicate.Data.Iterator.ParaImpl n (p1 : ps)) [a] Data.Type.Equality.~ [Predicate.Core.PP p a], GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Iterator.ParaImpl n (p : p1 : ps)) [a]
+ Predicate.Data.Iterator: instance forall k (p :: k) a (n :: GHC.Types.Nat). (GHC.Show.Show (Predicate.Core.PP p a), GHC.TypeNats.KnownNat n, GHC.Show.Show a, Predicate.Core.P p a) => Predicate.Core.P (Predicate.Data.Iterator.ParaImpl n '[p]) [a]
+ Predicate.Data.Iterator: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Data.Iterator.ScanNAT q) x => Predicate.Core.P (Predicate.Data.Iterator.ScanNA q) x
+ Predicate.Data.Iterator: instance forall k a x (ps :: [k]). ([a] Data.Type.Equality.~ x, Predicate.Util.GetLen ps, Predicate.Core.P (Predicate.Data.Iterator.ParaImpl (Predicate.Util.LenT ps) ps) x) => Predicate.Core.P (Predicate.Data.Iterator.Para ps) x
+ Predicate.Data.Iterator: instance forall k1 k2 (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.IterateUntilT p f) x => Predicate.Core.P (Predicate.Data.Iterator.IterateUntil p f) x
+ Predicate.Data.Iterator: instance forall k1 k2 (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.IterateWhileT p f) x => Predicate.Core.P (Predicate.Data.Iterator.IterateWhile p f) x
+ Predicate.Data.Iterator: instance forall k1 k2 (q :: k2) a s (p :: k1) b. (Predicate.Core.PP q a Data.Type.Equality.~ s, Predicate.Core.PP p s Data.Type.Equality.~ GHC.Maybe.Maybe (b, s), Predicate.Core.P q a, Predicate.Core.P p s, GHC.Show.Show s, GHC.Show.Show b) => Predicate.Core.P (Predicate.Data.Iterator.Unfoldr p q) a
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (n :: k3) (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.IterateNUntilT n p f) x => Predicate.Core.P (Predicate.Data.Iterator.IterateNUntil n p f) x
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (n :: k3) (p :: k2) (f :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.IterateNWhileT n p f) x => Predicate.Core.P (Predicate.Data.Iterator.IterateNWhile n p f) x
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.FoldNT n p q) x => Predicate.Core.P (Predicate.Data.Iterator.FoldN n p q) x
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.ScanNT n p q) x => Predicate.Core.P (Predicate.Data.Iterator.ScanN n p q) x
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Iterator.FoldLT p q r) x => Predicate.Core.P (Predicate.Data.Iterator.Foldl p q r) x
+ Predicate.Data.Iterator: instance forall k1 k2 k3 (p :: k3) b a (q :: k2) x (r :: k1). (Predicate.Core.PP p (b, a) Data.Type.Equality.~ b, Predicate.Core.PP q x Data.Type.Equality.~ b, Predicate.Core.PP r x Data.Type.Equality.~ [a], Predicate.Core.P p (b, a), Predicate.Core.P q x, Predicate.Core.P r x, GHC.Show.Show b, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Iterator.Scanl p q r) x
+ Predicate.Data.Json: data EncodeJson (pretty :: Bool) p
+ Predicate.Data.Json: data EncodeJsonFile (pretty :: Bool) p q
+ Predicate.Data.Json: data ParseJson (t :: Type) p
+ Predicate.Data.Json: data ParseJson' t p
+ Predicate.Data.Json: data ParseJsonFile (t :: Type) p
+ Predicate.Data.Json: data ParseJsonFile' t p
+ Predicate.Data.Json: instance forall k (pretty :: GHC.Types.Bool) (p :: k) x. (Predicate.Util.GetBool pretty, Data.Aeson.Types.ToJSON.ToJSON (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Json.EncodeJson pretty p) x
+ Predicate.Data.Json: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Json.ParseJsonFileT t p) x => Predicate.Core.P (Predicate.Data.Json.ParseJsonFile t p) x
+ Predicate.Data.Json: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Json.ParseJsonT t p) x => Predicate.Core.P (Predicate.Data.Json.ParseJson t p) x
+ Predicate.Data.Json: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ Data.ByteString.Lazy.Internal.ByteString, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Data.Aeson.Types.FromJSON.FromJSON (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.Json.ParseJson' t p) x
+ Predicate.Data.Json: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Data.Aeson.Types.FromJSON.FromJSON (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.Json.ParseJsonFile' t p) x
+ Predicate.Data.Json: instance forall k1 k2 (pretty :: GHC.Types.Bool) (p :: k2) x (q :: k1). (Predicate.Util.GetBool pretty, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Data.Aeson.Types.ToJSON.ToJSON (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Json.EncodeJsonFile pretty p q) x
+ Predicate.Data.List: data Break p q
+ Predicate.Data.List: data ChunksOf n p
+ Predicate.Data.List: data Drop n p
+ Predicate.Data.List: data Elem p q
+ Predicate.Data.List: data EmptyList (t :: Type)
+ Predicate.Data.List: data EmptyList' t
+ Predicate.Data.List: data EmptyT (t :: Type -> Type) p
+ Predicate.Data.List: data Filter p q
+ Predicate.Data.List: data GroupBy p q
+ Predicate.Data.List: data Head p
+ Predicate.Data.List: data Init p
+ Predicate.Data.List: data Inits
+ Predicate.Data.List: data Intercalate p q
+ Predicate.Data.List: data Keep p q
+ Predicate.Data.List: data Last p
+ Predicate.Data.List: data Len
+ Predicate.Data.List: data Length p
+ Predicate.Data.List: data Max
+ Predicate.Data.List: data Min
+ Predicate.Data.List: data Ones p
+ Predicate.Data.List: data PadL n p q
+ Predicate.Data.List: data PadR n p q
+ Predicate.Data.List: data Partition p q
+ Predicate.Data.List: data PartitionBy t p q
+ Predicate.Data.List: data Product
+ Predicate.Data.List: data Remove p q
+ Predicate.Data.List: data Reverse
+ Predicate.Data.List: data ReverseL
+ Predicate.Data.List: data Rotate n p
+ Predicate.Data.List: data Singleton p
+ Predicate.Data.List: data SortBy p q
+ Predicate.Data.List: data SortOn p q
+ Predicate.Data.List: data SortOnDesc p q
+ Predicate.Data.List: data Span p q
+ Predicate.Data.List: data SplitAt n p
+ Predicate.Data.List: data SplitAts ns p
+ Predicate.Data.List: data Sum
+ Predicate.Data.List: data Tail p
+ Predicate.Data.List: data Tails
+ Predicate.Data.List: data Take n p
+ Predicate.Data.List: data Uncons
+ Predicate.Data.List: data Unsnoc
+ Predicate.Data.List: data Unzip
+ Predicate.Data.List: data Unzip3
+ Predicate.Data.List: data Zip p q
+ Predicate.Data.List: data ZipL l p q
+ Predicate.Data.List: data ZipR r p q
+ Predicate.Data.List: data ZipWith p q r
+ Predicate.Data.List: data p ++ q
+ Predicate.Data.List: infixl 5 +:
+ Predicate.Data.List: infixr 5 ++
+ Predicate.Data.List: instance (GHC.Classes.Ord a, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Max [a]
+ Predicate.Data.List: instance (GHC.Classes.Ord a, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Min [a]
+ Predicate.Data.List: instance (GHC.Num.Num a, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Product [a]
+ Predicate.Data.List: instance (GHC.Num.Num a, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Sum [a]
+ Predicate.Data.List: instance (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s)) => Predicate.Core.P Predicate.Data.List.Uncons s
+ Predicate.Data.List: instance (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s)) => Predicate.Core.P Predicate.Data.List.Unsnoc s
+ Predicate.Data.List: instance (GHC.Show.Show a, as Data.Type.Equality.~ [a]) => Predicate.Core.P Predicate.Data.List.Reverse as
+ Predicate.Data.List: instance (GHC.Show.Show t, Control.Lens.Internal.Iso.Reversing t) => Predicate.Core.P Predicate.Data.List.ReverseL t
+ Predicate.Data.List: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Inits x
+ Predicate.Data.List: instance ([a] Data.Type.Equality.~ x, GHC.Show.Show a) => Predicate.Core.P Predicate.Data.List.Tails x
+ Predicate.Data.List: instance Predicate.Core.P (Predicate.Data.List.EmptyList t) x
+ Predicate.Data.List: instance Predicate.Core.P Predicate.Data.List.Unzip3T x => Predicate.Core.P Predicate.Data.List.Unzip3 x
+ Predicate.Data.List: instance Predicate.Core.P Predicate.Data.List.UnzipT x => Predicate.Core.P Predicate.Data.List.Unzip x
+ Predicate.Data.List: instance forall k (p :: k) x a (t :: * -> *). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ a, GHC.Show.Show (t a), GHC.Show.Show a, GHC.Base.Alternative t) => Predicate.Core.P (Predicate.Data.List.EmptyT t p) x
+ Predicate.Data.List: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P p x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.List.Ones p) x
+ Predicate.Data.List: instance forall k (p :: k) x. Predicate.Core.P p x => Predicate.Core.P (Predicate.Data.List.Singleton p) x
+ Predicate.Data.List: instance forall k (t :: k) x. Predicate.Core.P (Predicate.Data.List.EmptyList' t) x
+ Predicate.Data.List: instance forall k s (p :: k) x. (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.List.Head p) x
+ Predicate.Data.List: instance forall k s (p :: k) x. (GHC.Show.Show (Predicate.Util.ConsT s), GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.List.Last p) x
+ Predicate.Data.List: instance forall k s (p :: k) x. (GHC.Show.Show s, Control.Lens.Cons.Cons s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.List.Tail p) x
+ Predicate.Data.List: instance forall k s (p :: k) x. (GHC.Show.Show s, Control.Lens.Cons.Snoc s s (Predicate.Util.ConsT s) (Predicate.Util.ConsT s), Predicate.Core.PP p x Data.Type.Equality.~ s, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.List.Init p) x
+ Predicate.Data.List: instance forall k1 k2 (keep :: GHC.Types.Bool) a (p :: k2) x (q :: k1). (Predicate.Util.GetBool keep, GHC.Classes.Eq a, GHC.Show.Show a, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.PP q x Data.Type.Equality.~ [a]) => Predicate.Core.P (Predicate.Data.List.KeepImpl keep p q) x
+ Predicate.Data.List: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Data.List.DropT n p) x => Predicate.Core.P (Predicate.Data.List.Drop n p) x
+ Predicate.Data.List: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Data.List.RotateT n p) x => Predicate.Core.P (Predicate.Data.List.Rotate n p) x
+ Predicate.Data.List: instance forall k1 k2 (n :: k2) (p :: k1) x. Predicate.Core.P (Predicate.Data.List.TakeT n p) x => Predicate.Core.P (Predicate.Data.List.Take n p) x
+ Predicate.Data.List: instance forall k1 k2 (ns :: k2) x (p :: k1) a n. (Predicate.Core.P ns x, Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ [a], GHC.Show.Show n, GHC.Show.Show a, Predicate.Core.PP ns x Data.Type.Equality.~ [n], GHC.Real.Integral n) => Predicate.Core.P (Predicate.Data.List.SplitAts ns p) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.FilterT p q) x => Predicate.Core.P (Predicate.Data.List.Filter p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.KeepT p q) x => Predicate.Core.P (Predicate.Data.List.Keep p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.RemoveT p q) x => Predicate.Core.P (Predicate.Data.List.Remove p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.SortOnDescT p q) x => Predicate.Core.P (Predicate.Data.List.SortOnDesc p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.SortOnT p q) x => Predicate.Core.P (Predicate.Data.List.SortOn p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.SpanT p q) x => Predicate.Core.P (Predicate.Data.List.Span p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) a (q :: k1) x. (Predicate.Core.P p (a, a), Predicate.Core.P q x, GHC.Show.Show a, Predicate.Core.PP q x Data.Type.Equality.~ [a], Predicate.Core.PP p (a, a) Data.Type.Equality.~ GHC.Types.Ordering) => Predicate.Core.P (Predicate.Data.List.SortBy p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) a (q :: k1). ([Predicate.Core.PP p a] Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Classes.Eq (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.List.Elem p q) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) a b (n :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ [b], Predicate.Core.P n a, Predicate.Core.P p a, GHC.Show.Show b, GHC.Real.Integral (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Data.List.ChunksOf n p) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) a b (n :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ [b], Predicate.Core.P n a, Predicate.Core.P p a, GHC.Show.Show b, GHC.Real.Integral (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Data.List.SplitAt n p) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) a x (q :: k1) y. (Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Data.List.Zip p q) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, GHC.Show.Show x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.List.Partition p q) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.PP q x Data.Type.Equality.~ [a]) => Predicate.Core.P (p Predicate.Data.List.++ q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.P p x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.List.Break p q) a
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP q x), Control.Lens.Cons.Cons (Predicate.Core.PP q x) (Predicate.Core.PP q x) (Predicate.Core.PP p x) (Predicate.Core.PP p x)) => Predicate.Core.P (p Predicate.Data.List.:+ q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x (q :: k1). (Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP q x), GHC.Show.Show (Predicate.Core.PP p x), Control.Lens.Cons.Snoc (Predicate.Core.PP p x) (Predicate.Core.PP p x) (Predicate.Core.PP q x) (Predicate.Core.PP q x)) => Predicate.Core.P (p Predicate.Data.List.+: q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x a (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.PP q x Data.Type.Equality.~ Predicate.Core.PP p x, Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.List.Intercalate p q) x
+ Predicate.Data.List: instance forall k1 k2 (p :: k2) x t (q :: k1) a. (Predicate.Core.P p x, GHC.Classes.Ord t, GHC.Show.Show x, GHC.Show.Show t, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p x Data.Type.Equality.~ t, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.List.PartitionBy t p q) a
+ Predicate.Data.List: instance forall k1 k2 k3 (l :: k3) a x (p :: k2) (q :: k1) y. (Predicate.Core.PP l a Data.Type.Equality.~ x, Predicate.Core.P l a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Data.List.ZipL l p q) a
+ Predicate.Data.List: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.PadLT n p q) x => Predicate.Core.P (Predicate.Data.List.PadL n p q) x
+ Predicate.Data.List: instance forall k1 k2 k3 (n :: k3) (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.List.PadRT n p q) x => Predicate.Core.P (Predicate.Data.List.PadR n p q) x
+ Predicate.Data.List: instance forall k1 k2 k3 (n :: k3) a (left :: GHC.Types.Bool) (p :: k2) (q :: k1). (Predicate.Core.P n a, Predicate.Util.GetBool left, GHC.Real.Integral (Predicate.Core.PP n a), [Predicate.Core.PP p a] Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.List.PadImpl left n p q) a
+ Predicate.Data.List: instance forall k1 k2 k3 (q :: k3) a x (r :: k2) y (p :: k1). (Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP r a Data.Type.Equality.~ [y], Predicate.Core.P q a, Predicate.Core.P r a, Predicate.Core.P p (x, y), GHC.Show.Show x, GHC.Show.Show y, GHC.Show.Show (Predicate.Core.PP p (x, y))) => Predicate.Core.P (Predicate.Data.List.ZipWith p q r) a
+ Predicate.Data.List: instance forall k1 k2 k3 (r :: k3) a y (p :: k2) x (q :: k1). (Predicate.Core.PP r a Data.Type.Equality.~ y, Predicate.Core.P r a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Data.List.ZipR r p q) a
+ Predicate.Data.List: instance forall k1 k2 k3 k4 (l :: k4) a x (r :: k3) y (p :: k2) (q :: k1). (Predicate.Core.PP l a Data.Type.Equality.~ x, Predicate.Core.PP r a Data.Type.Equality.~ y, Predicate.Core.P l a, Predicate.Core.P r a, Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Data.List.ZipPad l r p q) a
+ Predicate.Data.List: instance forall k1 k2 x (q :: k2) a (p :: k1). (GHC.Show.Show x, Predicate.Core.PP q a Data.Type.Equality.~ [x], Predicate.Core.PP p (x, x) Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p (x, x), Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.List.GroupBy p q) a
+ Predicate.Data.Maybe: data CatMaybes q
+ Predicate.Data.Maybe: data IsJust p
+ Predicate.Data.Maybe: data IsNothing p
+ Predicate.Data.Maybe: data Just'
+ Predicate.Data.Maybe: data JustDef p q
+ Predicate.Data.Maybe: data JustFail p q
+ Predicate.Data.Maybe: data MapMaybe p q
+ Predicate.Data.Maybe: data MaybeBool b p
+ Predicate.Data.Maybe: data MaybeIn p q
+ Predicate.Data.Maybe: data MkJust p
+ Predicate.Data.Maybe: data MkNothing (t :: Type)
+ Predicate.Data.Maybe: data MkNothing' t
+ Predicate.Data.Maybe: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.Maybe.Just' (GHC.Maybe.Maybe a)
+ Predicate.Data.Maybe: instance Predicate.Core.P (Predicate.Data.Maybe.MkNothing t) x
+ Predicate.Data.Maybe: instance forall k (p :: k) x a. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a) => Predicate.Core.P (Predicate.Data.Maybe.IsJust p) x
+ Predicate.Data.Maybe: instance forall k (p :: k) x a. (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Maybe.Maybe a) => Predicate.Core.P (Predicate.Data.Maybe.IsNothing p) x
+ Predicate.Data.Maybe: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Maybe.MkJust p) x
+ Predicate.Data.Maybe: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Data.Maybe.CatMaybesT q) x => Predicate.Core.P (Predicate.Data.Maybe.CatMaybes q) x
+ Predicate.Data.Maybe: instance forall k (t :: k) a. Predicate.Core.P (Predicate.Data.Maybe.MkNothing' t) a
+ Predicate.Data.Maybe: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Maybe.MapMaybeT p q) x => Predicate.Core.P (Predicate.Data.Maybe.MapMaybe p q) x
+ Predicate.Data.Maybe: instance forall k1 k2 (p :: k2) a (b :: k1). (GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P b a, Predicate.Core.P p a, Predicate.Core.PP b a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Maybe.MaybeBool b p) a
+ Predicate.Data.Maybe: instance forall k1 k2 (p :: k2) x (q :: k1) a. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Maybe.Maybe a, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Maybe.JustFail p q) x
+ Predicate.Data.Maybe: instance forall k1 k2 (p :: k2) x a (q :: k1). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Maybe.Maybe a, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Maybe.JustDef p q) x
+ Predicate.Data.Maybe: instance forall k1 k2 (q :: k2) a (p :: k1). (Predicate.Core.P q a, GHC.Show.Show a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.PP p (Data.Proxy.Proxy (Predicate.Core.PP q a)) Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p (Data.Proxy.Proxy (Predicate.Core.PP q a))) => Predicate.Core.P (Predicate.Data.Maybe.MaybeIn p q) (GHC.Maybe.Maybe a)
+ Predicate.Data.Monoid: data MConcat p
+ Predicate.Data.Monoid: data MEmpty2 (t :: Type)
+ Predicate.Data.Monoid: data MEmpty2' t
+ Predicate.Data.Monoid: data MEmptyP
+ Predicate.Data.Monoid: data MEmptyT (t :: Type)
+ Predicate.Data.Monoid: data MEmptyT' t
+ Predicate.Data.Monoid: data SConcat p
+ Predicate.Data.Monoid: data STimes n p
+ Predicate.Data.Monoid: data SapA
+ Predicate.Data.Monoid: data SapA' (t :: Type)
+ Predicate.Data.Monoid: data p <> q
+ Predicate.Data.Monoid: infixr 6 <>
+ Predicate.Data.Monoid: instance Predicate.Core.P (Predicate.Data.Monoid.MEmpty2T t) x => Predicate.Core.P (Predicate.Data.Monoid.MEmpty2 t) x
+ Predicate.Data.Monoid: instance Predicate.Core.P (Predicate.Data.Monoid.MEmptyTT t) x => Predicate.Core.P (Predicate.Data.Monoid.MEmptyT t) x
+ Predicate.Data.Monoid: instance Predicate.Core.P (Predicate.Data.Monoid.SapAT' t) x => Predicate.Core.P (Predicate.Data.Monoid.SapA' t) x
+ Predicate.Data.Monoid: instance Predicate.Core.P Predicate.Data.Monoid.MEmptyPT x => Predicate.Core.P Predicate.Data.Monoid.MEmptyP x
+ Predicate.Data.Monoid: instance Predicate.Core.P Predicate.Data.Monoid.SapAT x => Predicate.Core.P Predicate.Data.Monoid.SapA x
+ Predicate.Data.Monoid: instance forall k (f :: * -> *) a (t :: k). (GHC.Show.Show (f a), GHC.Show.Show (f (Predicate.Core.PP t (f a))), GHC.Base.Functor f, GHC.Base.Monoid (Predicate.Core.PP t (f a))) => Predicate.Core.P (Predicate.Data.Monoid.MEmpty2' t) (f a)
+ Predicate.Data.Monoid: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.NonEmpty a, Predicate.Core.P p x, GHC.Show.Show a, GHC.Base.Semigroup a) => Predicate.Core.P (Predicate.Data.Monoid.SConcat p) x
+ Predicate.Data.Monoid: instance forall k (p :: k) x a. (Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P p x, GHC.Show.Show a, GHC.Base.Monoid a) => Predicate.Core.P (Predicate.Data.Monoid.MConcat p) x
+ Predicate.Data.Monoid: instance forall k (t :: k) a. (GHC.Show.Show (Predicate.Core.PP t a), GHC.Base.Monoid (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Data.Monoid.MEmptyT' t) a
+ Predicate.Data.Monoid: instance forall k1 k2 (n :: k2) a (p :: k1). (Predicate.Core.P n a, GHC.Real.Integral (Predicate.Core.PP n a), GHC.Base.Semigroup (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Monoid.STimes n p) a
+ Predicate.Data.Monoid: instance forall k1 k2 (p :: k2) x (q :: k1). (GHC.Base.Semigroup (Predicate.Core.PP p x), Predicate.Core.PP p x Data.Type.Equality.~ Predicate.Core.PP q x, Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (p Predicate.Data.Monoid.<> q) x
+ Predicate.Data.Numeric: data Abs p
+ Predicate.Data.Numeric: data Ceiling (t :: Type) p
+ Predicate.Data.Numeric: data Ceiling' t p
+ Predicate.Data.Numeric: data Div p q
+ Predicate.Data.Numeric: data DivMod p q
+ Predicate.Data.Numeric: data Even
+ Predicate.Data.Numeric: data Floor (t :: Type) p
+ Predicate.Data.Numeric: data Floor' t p
+ Predicate.Data.Numeric: data FromInteger (t :: Type) p
+ Predicate.Data.Numeric: data FromInteger' t n
+ Predicate.Data.Numeric: data FromIntegral (t :: Type) p
+ Predicate.Data.Numeric: data FromIntegral' t n
+ Predicate.Data.Numeric: data FromRational (t :: Type) p
+ Predicate.Data.Numeric: data FromRational' t r
+ Predicate.Data.Numeric: data LogBase p q
+ Predicate.Data.Numeric: data Mod p q
+ Predicate.Data.Numeric: data Negate p
+ Predicate.Data.Numeric: data Odd
+ Predicate.Data.Numeric: data Quot p q
+ Predicate.Data.Numeric: data QuotRem p q
+ Predicate.Data.Numeric: data ReadBase (t :: Type) (n :: Nat) p
+ Predicate.Data.Numeric: data ReadBase' t (n :: Nat) p
+ Predicate.Data.Numeric: data Rem p q
+ Predicate.Data.Numeric: data ShowBase (n :: Nat) p
+ Predicate.Data.Numeric: data Signum p
+ Predicate.Data.Numeric: data ToRational p
+ Predicate.Data.Numeric: data Truncate (t :: Type) p
+ Predicate.Data.Numeric: data Truncate' t p
+ Predicate.Data.Numeric: data p -% q
+ Predicate.Data.Numeric: infixl 6 -
+ Predicate.Data.Numeric: infixl 7 /
+ Predicate.Data.Numeric: infixl 8 -%
+ Predicate.Data.Numeric: infixr 8 **
+ Predicate.Data.Numeric: instance GHC.Classes.Eq Predicate.Data.Numeric.BinOp
+ Predicate.Data.Numeric: instance GHC.Show.Show Predicate.Data.Numeric.BinOp
+ Predicate.Data.Numeric: instance Predicate.Core.P Predicate.Data.Numeric.EvenT x => Predicate.Core.P Predicate.Data.Numeric.Even x
+ Predicate.Data.Numeric: instance Predicate.Core.P Predicate.Data.Numeric.OddT x => Predicate.Core.P Predicate.Data.Numeric.Odd x
+ Predicate.Data.Numeric: instance Predicate.Data.Numeric.GetBinOp 'Predicate.Data.Numeric.BAdd
+ Predicate.Data.Numeric: instance Predicate.Data.Numeric.GetBinOp 'Predicate.Data.Numeric.BMult
+ Predicate.Data.Numeric: instance Predicate.Data.Numeric.GetBinOp 'Predicate.Data.Numeric.BSub
+ Predicate.Data.Numeric: instance forall k (p :: k) x a (n :: GHC.Types.Nat). (Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P p x, GHC.Show.Show a, 2 GHC.TypeNats.<= n, n GHC.TypeNats.<= 36, GHC.TypeNats.KnownNat n, GHC.Real.Integral a) => Predicate.Core.P (Predicate.Data.Numeric.ShowBase n p) x
+ Predicate.Data.Numeric: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Numeric.Abs p) x
+ Predicate.Data.Numeric: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Numeric.Negate p) x
+ Predicate.Data.Numeric: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), GHC.Num.Num (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Numeric.Signum p) x
+ Predicate.Data.Numeric: instance forall k a (p :: k) x. (a Data.Type.Equality.~ Predicate.Core.PP p x, GHC.Show.Show a, GHC.Real.Real a, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Numeric.ToRational p) x
+ Predicate.Data.Numeric: instance forall k t (n :: GHC.Types.Nat) (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.ReadBaseT t n p) x => Predicate.Core.P (Predicate.Data.Numeric.ReadBase t n p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.CeilingT t p) x => Predicate.Core.P (Predicate.Data.Numeric.Ceiling t p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.FloorT t p) x => Predicate.Core.P (Predicate.Data.Numeric.Floor t p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.FromIntegerT t p) x => Predicate.Core.P (Predicate.Data.Numeric.FromInteger t p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.FromIntegralT t p) x => Predicate.Core.P (Predicate.Data.Numeric.FromIntegral t p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.FromRationalT t p) x => Predicate.Core.P (Predicate.Data.Numeric.FromRational t p) x
+ Predicate.Data.Numeric: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.Numeric.TruncateT t p) x => Predicate.Core.P (Predicate.Data.Numeric.Truncate t p) x
+ Predicate.Data.Numeric: instance forall k1 k2 (op :: Predicate.Data.Numeric.BinOp) (p :: k2) a (q :: k1). (Predicate.Data.Numeric.GetBinOp op, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Num.Num (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.Bin op p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.AddT p q) x => Predicate.Core.P (p Predicate.Data.Numeric.+ q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.MultT p q) x => Predicate.Core.P (p Predicate.Data.Numeric.* q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.NegateRatioT p q) x => Predicate.Core.P (p Predicate.Data.Numeric.-% q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.QuotT p q) x => Predicate.Core.P (Predicate.Data.Numeric.Quot p q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.RemT p q) x => Predicate.Core.P (Predicate.Data.Numeric.Rem p q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Numeric.SubT p q) x => Predicate.Core.P (p Predicate.Data.Numeric.- q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q a), GHC.Num.Num (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP q a)) => Predicate.Core.P (p Predicate.Data.Numeric.^ q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, GHC.Classes.Eq (Predicate.Core.PP q a), Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Fractional (Predicate.Core.PP p a)) => Predicate.Core.P (p Predicate.Data.Numeric./ q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Float.Floating (Predicate.Core.PP p a), GHC.Classes.Ord (Predicate.Core.PP q a)) => Predicate.Core.P (p Predicate.Data.Numeric.** q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.Div p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.DivMod p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.Mod p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Real.Integral (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.QuotRem p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP q a), GHC.Float.Floating (Predicate.Core.PP q a), GHC.Classes.Ord (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.LogBase p q) a
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) x (q :: k1). (GHC.Real.Integral (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP q x), GHC.Classes.Eq (Predicate.Core.PP q x), Predicate.Core.P p x, Predicate.Core.P q x, GHC.Show.Show (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP q x)) => Predicate.Core.P (p Predicate.Data.Numeric.% q) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.Numeric.Ceiling' t p) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.Numeric.Floor' t p) x
+ Predicate.Data.Numeric: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x, GHC.Show.Show (Predicate.Core.PP t x), GHC.Real.RealFrac (Predicate.Core.PP p x), GHC.Real.Integral (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.Numeric.Truncate' t p) x
+ Predicate.Data.Numeric: instance forall k1 k2 (r :: k2) a (t :: k1). (Predicate.Core.P r a, Predicate.Core.PP r a Data.Type.Equality.~ GHC.Real.Rational, GHC.Show.Show (Predicate.Core.PP t a), GHC.Real.Fractional (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Data.Numeric.FromRational' t r) a
+ Predicate.Data.Numeric: instance forall k1 k2 (t :: k2) a (n :: k1). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP n a), Predicate.Core.P n a, GHC.Show.Show (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Data.Numeric.FromInteger' t n) a
+ Predicate.Data.Numeric: instance forall k1 k2 (t :: k2) a (n :: k1). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP n a), Predicate.Core.P n a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP n a)) => Predicate.Core.P (Predicate.Data.Numeric.FromIntegral' t n) a
+ Predicate.Data.Numeric: instance forall k1 k2 (t :: k2) x (n :: GHC.Types.Nat) (p :: k1). (Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), Predicate.Util.ZwischenT 2 36 n, GHC.Show.Show (Predicate.Core.PP t x), GHC.Num.Num (Predicate.Core.PP t x), GHC.TypeNats.KnownNat n, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Numeric.ReadBase' t n p) x
+ Predicate.Data.Ordering: data AllNegative
+ Predicate.Data.Ordering: data AllPositive
+ Predicate.Data.Ordering: data Ands p
+ Predicate.Data.Ordering: data Asc
+ Predicate.Data.Ordering: data Asc'
+ Predicate.Data.Ordering: data Cmp (o :: OrderingP) p q
+ Predicate.Data.Ordering: data CmpI (o :: OrderingP) p q
+ Predicate.Data.Ordering: data Desc
+ Predicate.Data.Ordering: data Desc'
+ Predicate.Data.Ordering: data OrdA p
+ Predicate.Data.Ordering: data OrdA' p q
+ Predicate.Data.Ordering: data Ors p
+ Predicate.Data.Ordering: data p ===~ q
+ Predicate.Data.Ordering: infix 4 ===~
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.AllNegativeT x => Predicate.Core.P Predicate.Data.Ordering.AllNegative x
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.AllPositiveT x => Predicate.Core.P Predicate.Data.Ordering.AllPositive x
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.AscT x => Predicate.Core.P Predicate.Data.Ordering.Asc x
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.AscT' x => Predicate.Core.P Predicate.Data.Ordering.Asc' x
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.DescT x => Predicate.Core.P Predicate.Data.Ordering.Desc x
+ Predicate.Data.Ordering: instance Predicate.Core.P Predicate.Data.Ordering.DescT' x => Predicate.Core.P Predicate.Data.Ordering.Desc' x
+ Predicate.Data.Ordering: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Ordering.Ands p) x
+ Predicate.Data.Ordering: instance forall k (p :: k) x (t :: * -> *) a. (Predicate.Core.PP p x Data.Type.Equality.~ t a, Predicate.Core.P p x, GHC.Show.Show (t a), Data.Foldable.Foldable t, a Data.Type.Equality.~ GHC.Types.Bool) => Predicate.Core.P (Predicate.Data.Ordering.Ors p) x
+ Predicate.Data.Ordering: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.Ordering.OrdA' p p) x => Predicate.Core.P (Predicate.Data.Ordering.OrdA p) x
+ Predicate.Data.Ordering: instance forall k1 k2 (o :: Predicate.Util.OrderingP) (p :: k2) a (q :: k1). (Predicate.Util.GetOrd o, GHC.Classes.Ord (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.Ordering.Cmp o p q) a
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CEq p q) x => Predicate.Core.P (p Predicate.Data.Ordering.== q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CGe p q) x => Predicate.Core.P (p Predicate.Data.Ordering.>= q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CGt p q) x => Predicate.Core.P (p Predicate.Data.Ordering.> q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CLe p q) x => Predicate.Core.P (p Predicate.Data.Ordering.<= q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CLt p q) x => Predicate.Core.P (p Predicate.Data.Ordering.< q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.Cmp 'Predicate.Util.CNe p q) x => Predicate.Core.P (p Predicate.Data.Ordering./= q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CEq p q) x => Predicate.Core.P (p Predicate.Data.Ordering.==~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CGe p q) x => Predicate.Core.P (p Predicate.Data.Ordering.>=~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CGt p q) x => Predicate.Core.P (p Predicate.Data.Ordering.>~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CLe p q) x => Predicate.Core.P (p Predicate.Data.Ordering.<=~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CLt p q) x => Predicate.Core.P (p Predicate.Data.Ordering.<~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.CmpI 'Predicate.Util.CNe p q) x => Predicate.Core.P (p Predicate.Data.Ordering./=~ q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Ordering.OrdAT' p q) x => Predicate.Core.P (Predicate.Data.Ordering.OrdA' p q) x
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) a (o :: Predicate.Util.OrderingP) (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Util.GetOrd o, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (Predicate.Data.Ordering.CmpI o p q) a
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) a (q :: k1). (GHC.Classes.Ord (Predicate.Core.PP p a), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP q a), Predicate.Core.P q a) => Predicate.Core.P (p Predicate.Data.Ordering.==! q) a
+ Predicate.Data.Ordering: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.PP p a Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q a, Predicate.Core.P p a, Predicate.Core.P q a) => Predicate.Core.P (p Predicate.Data.Ordering.===~ q) a
+ Predicate.Data.Ordering: type Ge n = I >= n
+ Predicate.Data.Ordering: type Gt n = I > n
+ Predicate.Data.Ordering: type Le n = I <= n
+ Predicate.Data.Ordering: type Lt n = I < n
+ Predicate.Data.Ordering: type Ne n = I /= n
+ Predicate.Data.Ordering: type Negative = Lt 0
+ Predicate.Data.Ordering: type OrdI p q = p ===~ q
+ Predicate.Data.Ordering: type OrdP p q = p ==! q
+ Predicate.Data.Ordering: type Positive = Gt 0
+ Predicate.Data.Ordering: type Same n = I == n
+ Predicate.Data.ReadShow: class PrintC x
+ Predicate.Data.ReadShow: data PrintF s p
+ Predicate.Data.ReadShow: data PrintL (n :: Nat) s p
+ Predicate.Data.ReadShow: data PrintT s p
+ Predicate.Data.ReadShow: data ReadMaybe (t :: Type) p
+ Predicate.Data.ReadShow: data ReadMaybe' t p
+ Predicate.Data.ReadShow: data ReadP (t :: Type) p
+ Predicate.Data.ReadShow: data ReadP' t p
+ Predicate.Data.ReadShow: data ShowP p
+ Predicate.Data.ReadShow: instance (Text.Printf.PrintfArg a, Predicate.Data.ReadShow.PrintC rs) => Predicate.Data.ReadShow.PrintC (a, rs)
+ Predicate.Data.ReadShow: instance Predicate.Data.ReadShow.PrintC ()
+ Predicate.Data.ReadShow: instance forall k (p :: k) x. (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.ReadShow.ShowP p) x
+ Predicate.Data.ReadShow: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.ReadShow.ReadMaybeT t p) x => Predicate.Core.P (Predicate.Data.ReadShow.ReadMaybe t p) x
+ Predicate.Data.ReadShow: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.ReadShow.ReadPT t p) x => Predicate.Core.P (Predicate.Data.ReadShow.ReadP t p) x
+ Predicate.Data.ReadShow: instance forall k1 k2 (n :: GHC.Types.Nat) bs b a (s :: k2) x (p :: k1). (GHC.TypeNats.KnownNat n, Predicate.Data.ReadShow.PrintC bs, (b, bs) Data.Type.Equality.~ Predicate.Util.InductListP n a, Predicate.Util.InductListC n a, Text.Printf.PrintfArg b, Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p x Data.Type.Equality.~ [a], Predicate.Core.P s x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.ReadShow.PrintL n s p) x
+ Predicate.Data.ReadShow: instance forall k1 k2 (p :: k2) x (s :: k1). (Text.Printf.PrintfArg (Predicate.Core.PP p x), GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P s x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.ReadShow.PrintF s p) x
+ Predicate.Data.ReadShow: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Read.Read (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.ReadShow.ReadMaybe' t p) x
+ Predicate.Data.ReadShow: instance forall k1 k2 (p :: k2) x (t :: k1). (Predicate.Core.P p x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), GHC.Read.Read (Predicate.Core.PP t x)) => Predicate.Core.P (Predicate.Data.ReadShow.ReadP' t p) x
+ Predicate.Data.ReadShow: instance forall k1 k2 bs b y (s :: k2) x (p :: k1). (Predicate.Data.ReadShow.PrintC bs, (b, bs) Data.Type.Equality.~ Predicate.Util.InductTupleP y, Predicate.Util.InductTupleC y, Text.Printf.PrintfArg b, Predicate.Core.PP s x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP p x Data.Type.Equality.~ y, Predicate.Core.P s x, Predicate.Core.P p x, Predicate.Data.ReadShow.CheckT (Predicate.Core.PP p x) Data.Type.Equality.~ 'GHC.Types.True) => Predicate.Core.P (Predicate.Data.ReadShow.PrintT s p) x
+ Predicate.Data.Regex: data Re p q
+ Predicate.Data.Regex: data Re' (rs :: [ROpt]) p q
+ Predicate.Data.Regex: data ReplaceAll p q r
+ Predicate.Data.Regex: data ReplaceAll' (rs :: [ROpt]) p q r
+ Predicate.Data.Regex: data ReplaceAllString o p q r
+ Predicate.Data.Regex: data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
+ Predicate.Data.Regex: data ReplaceFn (o :: ReplaceFnSub) p
+ Predicate.Data.Regex: data ReplaceFn1 p
+ Predicate.Data.Regex: data ReplaceFn2 p
+ Predicate.Data.Regex: data ReplaceFn3 p
+ Predicate.Data.Regex: data ReplaceOne p q r
+ Predicate.Data.Regex: data ReplaceOne' (rs :: [ROpt]) p q r
+ Predicate.Data.Regex: data ReplaceOneString (o :: ReplaceFnSub) p q r
+ Predicate.Data.Regex: data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
+ Predicate.Data.Regex: data Rescan p q
+ Predicate.Data.Regex: data Rescan' (rs :: [ROpt]) p q
+ Predicate.Data.Regex: data RescanRanges p q
+ Predicate.Data.Regex: data RescanRanges' (rs :: [ROpt]) p q
+ Predicate.Data.Regex: data Resplit p q
+ Predicate.Data.Regex: data Resplit' (rs :: [ROpt]) p q
+ Predicate.Data.Regex: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ (GHC.Base.String -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Regex.ReplaceFn2 p) x
+ Predicate.Data.Regex: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ (GHC.Base.String -> [GHC.Base.String] -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Regex.ReplaceFn1 p) x
+ Predicate.Data.Regex: instance forall k (p :: k) x. (Predicate.Core.PP p x Data.Type.Equality.~ ([GHC.Base.String] -> GHC.Base.String), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Regex.ReplaceFn3 p) x
+ Predicate.Data.Regex: instance forall k (r :: Predicate.Util.ReplaceFnSub) (p :: k) x. (Predicate.Util.GetReplaceFnSub r, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.Regex.ReplaceFn r p) x
+ Predicate.Data.Regex: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReT p q) x => Predicate.Core.P (Predicate.Data.Regex.Re p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Regex.RescanRangesT p q) x => Predicate.Core.P (Predicate.Data.Regex.RescanRanges p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Regex.RescanT p q) x => Predicate.Core.P (Predicate.Data.Regex.Rescan p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ResplitT p q) x => Predicate.Core.P (Predicate.Data.Regex.Resplit p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Regex.Re' rs p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Regex.Rescan' rs p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Regex.RescanRanges' rs p q) x
+ Predicate.Data.Regex: instance forall k1 k2 (rs :: [Predicate.Util.ROpt]) (p :: k2) x (q :: k1). (Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.Regex.Resplit' rs p q) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (b :: GHC.Types.Bool) (rs :: [Predicate.Util.ROpt]) (p :: k3) x (q :: k2) (r :: k1). (Predicate.Util.GetBool b, Predicate.Util.GetROpts rs, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Predicate.Util.RReplace, Predicate.Core.PP r x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Data.Regex.ReplaceImpl b rs p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceAllStringT o p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceAllString o p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceOneStringT o p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceOneString o p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceAllT p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceAll p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceOneT p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceOne p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceAllStringT' rs o p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceAllString' rs o p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (o :: Predicate.Util.ReplaceFnSub) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceOneStringT' rs o p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceOneString' rs o p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceAllT' rs p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceAll' rs p q r) x
+ Predicate.Data.Regex: instance forall k1 k2 k3 (rs :: [Predicate.Util.ROpt]) (p :: k3) (q :: k2) (r :: k1) x. Predicate.Core.P (Predicate.Data.Regex.ReplaceOneT' rs p q r) x => Predicate.Core.P (Predicate.Data.Regex.ReplaceOne' rs p q r) x
+ Predicate.Data.String: data FromString (t :: Type) p
+ Predicate.Data.String: data FromString' t s
+ Predicate.Data.String: data IsInfix p q
+ Predicate.Data.String: data IsInfixI p q
+ Predicate.Data.String: data IsPrefix p q
+ Predicate.Data.String: data IsPrefixI p q
+ Predicate.Data.String: data IsSuffix p q
+ Predicate.Data.String: data IsSuffixI p q
+ Predicate.Data.String: data StripL p q
+ Predicate.Data.String: data StripR p q
+ Predicate.Data.String: data ToString p
+ Predicate.Data.String: data TrimBoth p
+ Predicate.Data.String: data TrimL p
+ Predicate.Data.String: data TrimR p
+ Predicate.Data.String: instance Predicate.Data.String.ToStringC Data.ByteString.Internal.ByteString
+ Predicate.Data.String: instance Predicate.Data.String.ToStringC Data.ByteString.Lazy.Internal.ByteString
+ Predicate.Data.String: instance Predicate.Data.String.ToStringC Data.Text.Internal.Lazy.Text
+ Predicate.Data.String: instance Predicate.Data.String.ToStringC Data.Text.Internal.Text
+ Predicate.Data.String: instance Predicate.Data.String.ToStringC GHC.Base.String
+ Predicate.Data.String: instance forall k (l :: GHC.Types.Bool) (r :: GHC.Types.Bool) (p :: k) x. (Predicate.Util.FailUnlessT (Predicate.Util.OrT l r) ('GHC.TypeLits.Text "TrimImpl: left and right cannot both be False"), Predicate.Util.GetBool l, Predicate.Util.GetBool r, Data.Text.Lens.IsText (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.String.TrimImpl l r p) x
+ Predicate.Data.String: instance forall k (p :: k) x. (Predicate.Data.String.ToStringC (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.String.ToString p) x
+ Predicate.Data.String: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.String.TrimBothT p) x => Predicate.Core.P (Predicate.Data.String.TrimBoth p) x
+ Predicate.Data.String: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.String.TrimLT p) x => Predicate.Core.P (Predicate.Data.String.TrimL p) x
+ Predicate.Data.String: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.String.TrimRT p) x => Predicate.Core.P (Predicate.Data.String.TrimR p) x
+ Predicate.Data.String: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.String.FromStringPT t p) x => Predicate.Core.P (Predicate.Data.String.FromString t p) x
+ Predicate.Data.String: instance forall k1 k2 (ignore :: GHC.Types.Bool) (p :: k2) x (q :: k1) (cmp :: GHC.Types.Ordering). (Predicate.Util.GetBool ignore, Predicate.Core.P p x, Predicate.Core.P q x, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ GHC.Base.String, Predicate.Util.GetOrdering cmp) => Predicate.Core.P (Predicate.Data.String.IsFixImpl cmp ignore p q) x
+ Predicate.Data.String: instance forall k1 k2 (l :: GHC.Types.Bool) (p :: k2) x (q :: k1). (Predicate.Util.GetBool l, Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.P p x, Data.Text.Lens.IsText (Predicate.Core.PP q x), Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.String.StripImpl l p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsInfixIT p q) x => Predicate.Core.P (Predicate.Data.String.IsInfixI p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsInfixT p q) x => Predicate.Core.P (Predicate.Data.String.IsInfix p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsPrefixIT p q) x => Predicate.Core.P (Predicate.Data.String.IsPrefixI p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsPrefixT p q) x => Predicate.Core.P (Predicate.Data.String.IsPrefix p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsSuffixIT p q) x => Predicate.Core.P (Predicate.Data.String.IsSuffixI p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.IsSuffixT p q) x => Predicate.Core.P (Predicate.Data.String.IsSuffix p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.StripLT p q) x => Predicate.Core.P (Predicate.Data.String.StripL p q) x
+ Predicate.Data.String: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.String.StripRT p q) x => Predicate.Core.P (Predicate.Data.String.StripR p q) x
+ Predicate.Data.String: instance forall k1 k2 (s :: k2) a (t :: k1). (Predicate.Core.P s a, Predicate.Core.PP s a Data.Type.Equality.~ GHC.Base.String, GHC.Show.Show (Predicate.Core.PP t a), Data.String.IsString (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Data.String.FromString' t s) a
+ Predicate.Data.These: data Assoc
+ Predicate.Data.These: data Heres
+ Predicate.Data.These: data IsThat p
+ Predicate.Data.These: data IsThese p
+ Predicate.Data.These: data IsThis p
+ Predicate.Data.These: data MkThat (t :: Type) p
+ Predicate.Data.These: data MkThat' t p
+ Predicate.Data.These: data MkThese p q
+ Predicate.Data.These: data MkThis (t :: Type) p
+ Predicate.Data.These: data MkThis' t p
+ Predicate.Data.These: data PartitionThese
+ Predicate.Data.These: data That'
+ Predicate.Data.These: data ThatDef p q
+ Predicate.Data.These: data ThatFail p q
+ Predicate.Data.These: data Thats
+ Predicate.Data.These: data Theres
+ Predicate.Data.These: data These'
+ Predicate.Data.These: data TheseDef p q
+ Predicate.Data.These: data TheseFail p q
+ Predicate.Data.These: data TheseId p q
+ Predicate.Data.These: data TheseIn p q r
+ Predicate.Data.These: data TheseX p q r s
+ Predicate.Data.These: data Theses
+ Predicate.Data.These: data This'
+ Predicate.Data.These: data ThisDef p q
+ Predicate.Data.These: data ThisFail p q
+ Predicate.Data.These: data Thiss
+ Predicate.Data.These: data Unassoc
+ Predicate.Data.These: data ZipThese p q
+ Predicate.Data.These: instance (GHC.Show.Show (p (p a b) c), GHC.Show.Show (p a (p b c)), Predicate.Data.These.AssocC p) => Predicate.Core.P Predicate.Data.These.Assoc (p (p a b) c)
+ Predicate.Data.These: instance (GHC.Show.Show (p (p a b) c), GHC.Show.Show (p a (p b c)), Predicate.Data.These.AssocC p) => Predicate.Core.P Predicate.Data.These.Unassoc (p a (p b c))
+ Predicate.Data.These: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Data.These.Heres [Data.These.These a b]
+ Predicate.Data.These: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Data.These.PartitionThese [Data.These.These a b]
+ Predicate.Data.These: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Data.These.Theres [Data.These.These a b]
+ Predicate.Data.These: instance (GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P Predicate.Data.These.These' (Data.These.These a b)
+ Predicate.Data.These: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.These.That' (Data.These.These x a)
+ Predicate.Data.These: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.These.This' (Data.These.These a x)
+ Predicate.Data.These: instance Predicate.Core.P Predicate.Data.These.ThatsT x => Predicate.Core.P Predicate.Data.These.Thats x
+ Predicate.Data.These: instance Predicate.Core.P Predicate.Data.These.ThesesT x => Predicate.Core.P Predicate.Data.These.Theses x
+ Predicate.Data.These: instance Predicate.Core.P Predicate.Data.These.ThissT x => Predicate.Core.P Predicate.Data.These.Thiss x
+ Predicate.Data.These: instance Predicate.Data.These.AssocC (,)
+ Predicate.Data.These: instance Predicate.Data.These.AssocC Data.Either.Either
+ Predicate.Data.These: instance Predicate.Data.These.AssocC Data.These.These
+ Predicate.Data.These: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.These.IsThatT p) x => Predicate.Core.P (Predicate.Data.These.IsThat p) x
+ Predicate.Data.These: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.These.IsTheseT p) x => Predicate.Core.P (Predicate.Data.These.IsThese p) x
+ Predicate.Data.These: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.These.IsThisT p) x => Predicate.Core.P (Predicate.Data.These.IsThis p) x
+ Predicate.Data.These: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.These.MkThatT t p) x => Predicate.Core.P (Predicate.Data.These.MkThat t p) x
+ Predicate.Data.These: instance forall k t (p :: k) x. Predicate.Core.P (Predicate.Data.These.MkThisT t p) x => Predicate.Core.P (Predicate.Data.These.MkThis t p) x
+ Predicate.Data.These: instance forall k x1 x2 (p :: k) x a b (th :: Data.These.These x1 x2). (Predicate.Core.PP p x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, GHC.Show.Show a, GHC.Show.Show b, Predicate.Util.GetThese th) => Predicate.Core.P (Predicate.Data.These.IsTh th p) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.These.TheseIdT p q) x => Predicate.Core.P (Predicate.Data.These.TheseId p q) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) a (q :: k1). (Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q a)) => Predicate.Core.P (Predicate.Data.These.MkThese p q) a
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) a x (q :: k1) y. (Predicate.Core.PP p a Data.Type.Equality.~ [x], Predicate.Core.PP q a Data.Type.Equality.~ [y], Predicate.Core.P p a, Predicate.Core.P q a, GHC.Show.Show x, GHC.Show.Show y) => Predicate.Core.P (Predicate.Data.These.ZipThese p q) a
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.These.ThatFail p q) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.These.TheseFail p q) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) x (q :: k1) a b. (Predicate.Core.PP p x Data.Type.Equality.~ GHC.Base.String, Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.P p x, Predicate.Core.P q x) => Predicate.Core.P (Predicate.Data.These.ThisFail p q) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.These.MkThat' t p) x
+ Predicate.Data.These: instance forall k1 k2 (p :: k2) x (t :: k1). (GHC.Show.Show (Predicate.Core.PP p x), Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.These.MkThis' t p) x
+ Predicate.Data.These: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ (a, b), Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.These.TheseDef p q) x
+ Predicate.Data.These: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ a, Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.These.ThisDef p q) x
+ Predicate.Data.These: instance forall k1 k2 (q :: k2) x a b (p :: k1). (Predicate.Core.PP q x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p x Data.Type.Equality.~ b, Predicate.Core.P q x, Predicate.Core.P p x) => Predicate.Core.P (Predicate.Data.These.ThatDef p q) x
+ Predicate.Data.These: instance forall k1 k2 k3 a b (p :: k3) (q :: k2) (r :: k1). (GHC.Show.Show a, GHC.Show.Show b, GHC.Show.Show (Predicate.Core.PP p a), Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r (a, b), Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP q b, Predicate.Core.PP p a Data.Type.Equality.~ Predicate.Core.PP r (a, b), Predicate.Core.PP q b Data.Type.Equality.~ Predicate.Core.PP r (a, b)) => Predicate.Core.P (Predicate.Data.These.TheseIn p q r) (Data.These.These a b)
+ Predicate.Data.These: instance forall k1 k2 k3 k4 (s :: k4) x (p :: k3) a (q :: k2) b (r :: k1) c. (Predicate.Core.P s x, Predicate.Core.P p (x, a), Predicate.Core.P q (x, b), Predicate.Core.P r (x, (a, b)), Predicate.Core.PP s x Data.Type.Equality.~ Data.These.These a b, Predicate.Core.PP p (x, a) Data.Type.Equality.~ c, Predicate.Core.PP q (x, b) Data.Type.Equality.~ c, Predicate.Core.PP r (x, (a, b)) Data.Type.Equality.~ c) => Predicate.Core.P (Predicate.Data.These.TheseX p q r s) x
+ Predicate.Data.Tuple: data AndA p q r
+ Predicate.Data.Tuple: data Dup
+ Predicate.Data.Tuple: data First p
+ Predicate.Data.Tuple: data OrA p q r
+ Predicate.Data.Tuple: data Pairs
+ Predicate.Data.Tuple: data Second q
+ Predicate.Data.Tuple: data p |+ q
+ Predicate.Data.Tuple: infixr 3 |+
+ Predicate.Data.Tuple: instance GHC.Show.Show a => Predicate.Core.P Predicate.Data.Tuple.Pairs [a]
+ Predicate.Data.Tuple: instance GHC.Show.Show x => Predicate.Core.P Predicate.Data.Tuple.Dup x
+ Predicate.Data.Tuple: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.Tuple.FirstT p) x => Predicate.Core.P (Predicate.Data.Tuple.First p) x
+ Predicate.Data.Tuple: instance forall k (q :: k) x. Predicate.Core.P (Predicate.Data.Tuple.SecondT q) x => Predicate.Core.P (Predicate.Data.Tuple.Second q) x
+ Predicate.Data.Tuple: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Tuple.AndAT p q) x => Predicate.Core.P (p Predicate.Data.Tuple.&* q) x
+ Predicate.Data.Tuple: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Tuple.OrAT p q) x => Predicate.Core.P (p Predicate.Data.Tuple.|+ q) x
+ Predicate.Data.Tuple: instance forall k1 k2 (p :: k2) (q :: k1) x. Predicate.Core.P (Predicate.Data.Tuple.WAmpT p q) x => Predicate.Core.P (p Predicate.Data.Tuple.&&& q) x
+ Predicate.Data.Tuple: instance forall k1 k2 (p :: k2) a (q :: k1) b. (GHC.Show.Show (Predicate.Core.PP p a), GHC.Show.Show (Predicate.Core.PP q b), Predicate.Core.P p a, Predicate.Core.P q b, GHC.Show.Show a, GHC.Show.Show b) => Predicate.Core.P (p Predicate.Data.Tuple.*** q) (a, b)
+ Predicate.Data.Tuple: instance forall k1 k2 k3 (r :: k3) x a b (p :: k2) (q :: k1). (Predicate.Core.PP r x Data.Type.Equality.~ (a, b), Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q b Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Data.Tuple.AndA p q r) x
+ Predicate.Data.Tuple: instance forall k1 k2 k3 (r :: k3) x a b (p :: k2) (q :: k1). (Predicate.Core.PP r x Data.Type.Equality.~ (a, b), Predicate.Core.PP p a Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.PP q b Data.Type.Equality.~ GHC.Types.Bool, Predicate.Core.P p a, Predicate.Core.P q b, Predicate.Core.P r x) => Predicate.Core.P (Predicate.Data.Tuple.OrA p q r) x
+ Predicate.Examples.Common: type Isbn10fmt = ConcatMap (ShowP Id) Id *** If (Id == 10) "X" (ShowP Id) >> Fst Id <> "-" <> Snd Id
+ Predicate.Examples.Common: type Isbn10ip = Resplit "-" Id >> Concat Id >> 'Just Unsnoc >> Map (ReadP Int (Singleton Id)) Id *** If (Singleton Id ==~ "X") 10 (ReadP Int (Singleton Id))
+ Predicate.Examples.Common: type Isbn10op = GuardSimple (All (0 <..> 9) (Fst Id) && Between 0 10 (Snd Id)) >> ZipWith (Fst Id * Snd Id) (1 ... 10 >> Reverse) (Fst Id +: Snd Id) >> Sum >> Guard "mod 0 oops" (Id `Mod` 11 == 0) >> 'True
+ Predicate.Examples.Common: type Isbn13fmt = 'Just Unsnoc >> ConcatMap (ShowP Id) (Fst Id) <> "-" <> ShowP (Snd Id)
+ Predicate.Examples.Common: type Isbn13ip = Resplit "-" Id >> Concat Id >> Map (ReadP Int (Singleton Id)) Id
+ Predicate.Examples.Common: type Isbn13op = ZipWith (Fst Id * Snd Id) (Cycle 13 [1, 3] >> Reverse) Id >> Sum >> '(Id, Id `Mod` 10) >> Guard (PrintT "sum=%d mod 10=%d" Id) (Snd Id == 0) >> 'True
+ Predicate.Examples.Refined2: isbn10 :: Proxy (Isbn10 opts)
+ Predicate.Examples.Refined2: isbn13 :: Proxy (Isbn13 opts)
+ Predicate.Examples.Refined2: type Isbn10 (opts :: OptT) = '(opts, Isbn10ip, Isbn10op, String)
+ Predicate.Examples.Refined2: type Isbn10R (opts :: OptT) = MakeR2 (Isbn10 opts)
+ Predicate.Examples.Refined2: type Isbn13 (opts :: OptT) = '(opts, Isbn13ip, Isbn13op, String)
+ Predicate.Examples.Refined2: type Isbn13R (opts :: OptT) = MakeR2 (Isbn13 opts)
+ Predicate.Examples.Refined3: isbn10 :: Proxy (Isbn10 opts)
+ Predicate.Examples.Refined3: isbn13 :: Proxy (Isbn13 opts)
+ Predicate.Examples.Refined3: type Isbn10 (opts :: OptT) = '(opts, Isbn10ip, Isbn10op, Isbn10fmt, String)
+ Predicate.Examples.Refined3: type Isbn10R (opts :: OptT) = MakeR3 (Isbn10 opts)
+ Predicate.Examples.Refined3: type Isbn13 (opts :: OptT) = '(opts, Isbn13ip, Isbn13op, Isbn13fmt, String)
+ Predicate.Examples.Refined3: type Isbn13R (opts :: OptT) = MakeR3 (Isbn13 opts)
+ Predicate.Refined3: newRefined3TIO :: forall opts ip op fmt i m. (Refined3C opts ip op fmt i, MonadIO m, Show (PP ip i), Show i) => i -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Util: badLength :: Foldable t => t a -> Int -> String
+ Predicate.Util: prtTree :: Show x => POpts -> TT x -> String
+ Predicate.Util: showIndex :: (Show i, Num i) => i -> String
- Predicate.Core: evalBoolHide :: forall m p a proxy. (MonadEval m, P p a, PP p a ~ Bool) => proxy p -> POpts -> a -> m (TT (PP p a))
+ Predicate.Core: evalBoolHide :: forall p a m. (MonadEval m, P p a, PP p a ~ Bool) => POpts -> a -> m (TT (PP p a))
- Predicate.Core: evalHide :: forall m p a proxy. (MonadEval m, P p a) => proxy p -> POpts -> a -> m (TT (PP p a))
+ Predicate.Core: evalHide :: forall p a m. (MonadEval m, P p a) => POpts -> a -> m (TT (PP p a))
- Predicate.Refined: convertRefinedT :: forall m opts p a p1 a1. (RefinedC opts p1 a1, Monad m) => (a -> a1) -> RefinedT m (Refined opts p a) -> RefinedT m (Refined opts p1 a1)
+ Predicate.Refined: convertRefinedT :: forall opts p a p1 a1 m. (RefinedC opts p1 a1, Monad m) => (a -> a1) -> RefinedT m (Refined opts p a) -> RefinedT m (Refined opts p1 a1)
- Predicate.Refined: newRefinedT :: forall m opts p a. (RefinedC opts p a, Monad m) => a -> RefinedT m (Refined opts p a)
+ Predicate.Refined: newRefinedT :: forall opts p a m. (RefinedC opts p a, Monad m) => a -> RefinedT m (Refined opts p a)
- Predicate.Refined: rapply :: forall m opts p a opts1 z. (z ~ (opts :# opts1), OptTC opts1, RefinedC opts p a, Monad m) => (a -> a -> a) -> RefinedT m (Refined opts p a) -> RefinedT m (Refined opts1 p a) -> RefinedT m (Refined z p a)
+ Predicate.Refined: rapply :: forall opts p a opts1 z m. (z ~ (opts :# opts1), OptTC opts1, RefinedC opts p a, Monad m) => (a -> a -> a) -> RefinedT m (Refined opts p a) -> RefinedT m (Refined opts1 p a) -> RefinedT m (Refined z p a)
- Predicate.Refined: rapplyLift :: forall m opts p a. (RefinedC opts p a, Monad m) => (a -> a -> a) -> Refined opts p a -> Refined opts p a -> RefinedT m (Refined opts p a)
+ Predicate.Refined: rapplyLift :: forall opts p a m. (RefinedC opts p a, Monad m) => (a -> a -> a) -> Refined opts p a -> Refined opts p a -> RefinedT m (Refined opts p a)
- Predicate.Refined1: convertRefined1TP :: forall m opts ip op fmt i ip1 op1 fmt1 i1. (Refined1C opts ip1 op1 fmt1 i1, Monad m, Show (PP ip i), PP ip i ~ PP ip1 i1, Show i1) => Proxy '(opts, ip, op, fmt, i) -> Proxy '(opts, ip1, op1, fmt1, i1) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip1 op1 fmt1 i1)
+ Predicate.Refined1: convertRefined1TP :: forall opts ip op fmt i ip1 op1 fmt1 i1 m. (Refined1C opts ip1 op1 fmt1 i1, Monad m, Show (PP ip i), PP ip i ~ PP ip1 i1, Show i1) => Proxy '(opts, ip, op, fmt, i) -> Proxy '(opts, ip1, op1, fmt1, i1) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip1 op1 fmt1 i1)
- Predicate.Refined1: eval1M :: forall m opts ip op fmt i. (MonadEval m, Refined1C opts ip op fmt i) => i -> m (RResults1 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined1 opts ip op fmt i))
+ Predicate.Refined1: eval1M :: forall opts ip op fmt i m. (MonadEval m, Refined1C opts ip op fmt i) => i -> m (RResults1 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined1 opts ip op fmt i))
- Predicate.Refined1: newRefined1T :: forall m opts ip op fmt i. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => i -> RefinedT m (Refined1 opts ip op fmt i)
+ Predicate.Refined1: newRefined1T :: forall opts ip op fmt i m. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => i -> RefinedT m (Refined1 opts ip op fmt i)
- Predicate.Refined1: newRefined1TP :: forall m opts ip op fmt i proxy. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined1 opts ip op fmt i)
+ Predicate.Refined1: newRefined1TP :: forall opts ip op fmt i proxy m. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined1 opts ip op fmt i)
- Predicate.Refined1: newRefined1TPIO :: forall m opts ip op fmt i proxy. (Refined1C opts ip op fmt i, MonadIO m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined1 opts ip op fmt i)
+ Predicate.Refined1: newRefined1TPIO :: forall opts ip op fmt i proxy m. (Refined1C opts ip op fmt i, MonadIO m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined1 opts ip op fmt i)
- Predicate.Refined1: rapply1 :: forall m opts ip op fmt i. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i)
+ Predicate.Refined1: rapply1 :: forall opts ip op fmt i m. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i)
- Predicate.Refined1: rapply1P :: forall m opts ip op fmt i proxy. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i)
+ Predicate.Refined1: rapply1P :: forall opts ip op fmt i proxy m. (Refined1C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i) -> RefinedT m (Refined1 opts ip op fmt i)
- Predicate.Refined1: withRefined1TP :: forall m opts ip op fmt i b proxy. (Monad m, Refined1C opts ip op fmt i, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> (Refined1 opts ip op fmt i -> RefinedT m b) -> RefinedT m b
+ Predicate.Refined1: withRefined1TP :: forall opts ip op fmt i b proxy m. (Monad m, Refined1C opts ip op fmt i, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> (Refined1 opts ip op fmt i -> RefinedT m b) -> RefinedT m b
- Predicate.Refined2: eval2M :: forall m opts ip op i. (MonadEval m, Refined2C opts ip op i) => i -> m (RResults2 (PP ip i), Maybe (Refined2 opts ip op i))
+ Predicate.Refined2: eval2M :: forall opts ip op i m. (MonadEval m, Refined2C opts ip op i) => i -> m (RResults2 (PP ip i), Maybe (Refined2 opts ip op i))
- Predicate.Refined2: newRefined2T :: forall m opts ip op i. (Refined2C opts ip op i, Monad m, Show (PP ip i)) => i -> RefinedT m (Refined2 opts ip op i)
+ Predicate.Refined2: newRefined2T :: forall opts ip op i m. (Refined2C opts ip op i, Monad m, Show (PP ip i)) => i -> RefinedT m (Refined2 opts ip op i)
- Predicate.Refined2: newRefined2TIO :: forall m opts ip op i. (Refined2C opts ip op i, MonadIO m, Show (PP ip i)) => i -> RefinedT m (Refined2 opts ip op i)
+ Predicate.Refined2: newRefined2TIO :: forall opts ip op i m. (Refined2C opts ip op i, MonadIO m, Show (PP ip i)) => i -> RefinedT m (Refined2 opts ip op i)
- Predicate.Refined2: newRefined2TP :: forall m opts ip op i proxy. (Refined2C opts ip op i, Monad m, Show (PP ip i)) => proxy '(opts, ip, op, i) -> i -> RefinedT m (Refined2 opts ip op i)
+ Predicate.Refined2: newRefined2TP :: forall opts ip op i proxy m. (Refined2C opts ip op i, Monad m, Show (PP ip i)) => proxy '(opts, ip, op, i) -> i -> RefinedT m (Refined2 opts ip op i)
- Predicate.Refined2: withRefined2TP :: forall m opts ip op i b proxy. (Monad m, Refined2C opts ip op i, Show (PP ip i)) => proxy '(opts, ip, op, i) -> i -> (Refined2 opts ip op i -> RefinedT m b) -> RefinedT m b
+ Predicate.Refined2: withRefined2TP :: forall opts ip op i b proxy m. (Monad m, Refined2C opts ip op i, Show (PP ip i)) => proxy '(opts, ip, op, i) -> i -> (Refined2 opts ip op i -> RefinedT m b) -> RefinedT m b
- Predicate.Refined3: convertRefined3TP :: forall m opts ip op fmt i ip1 op1 fmt1 i1. (Refined3C opts ip op fmt i, Refined3C opts ip1 op1 fmt1 i1, Monad m, Show (PP ip i), PP ip i ~ PP ip1 i1, Show i1) => Proxy '(opts, ip, op, fmt, i) -> Proxy '(opts, ip1, op1, fmt1, i1) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip1 op1 fmt1 i1)
+ Predicate.Refined3: convertRefined3TP :: forall opts ip op fmt i ip1 op1 fmt1 i1 m. (Refined3C opts ip op fmt i, Refined3C opts ip1 op1 fmt1 i1, Monad m, Show (PP ip i), PP ip i ~ PP ip1 i1, Show i1) => Proxy '(opts, ip, op, fmt, i) -> Proxy '(opts, ip1, op1, fmt1, i1) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip1 op1 fmt1 i1)
- Predicate.Refined3: eval3M :: forall m opts ip op fmt i. (MonadEval m, Refined3C opts ip op fmt i) => i -> m (RResults3 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined3 opts ip op fmt i))
+ Predicate.Refined3: eval3M :: forall opts ip op fmt i m. (MonadEval m, Refined3C opts ip op fmt i) => i -> m (RResults3 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined3 opts ip op fmt i))
- Predicate.Refined3: newRefined3T :: forall m opts ip op fmt i. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => i -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Refined3: newRefined3T :: forall opts ip op fmt i m. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => i -> RefinedT m (Refined3 opts ip op fmt i)
- Predicate.Refined3: newRefined3TP :: forall m opts ip op fmt i proxy. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Refined3: newRefined3TP :: forall opts ip op fmt i proxy m. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined3 opts ip op fmt i)
- Predicate.Refined3: newRefined3TPIO :: forall m opts ip op fmt i proxy. (Refined3C opts ip op fmt i, MonadIO m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Refined3: newRefined3TPIO :: forall opts ip op fmt i proxy m. (Refined3C opts ip op fmt i, MonadIO m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> RefinedT m (Refined3 opts ip op fmt i)
- Predicate.Refined3: rapply3 :: forall m opts ip op fmt i. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Refined3: rapply3 :: forall opts ip op fmt i m. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i)
- Predicate.Refined3: rapply3P :: forall m opts ip op fmt i proxy. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i)
+ Predicate.Refined3: rapply3P :: forall opts ip op fmt i proxy m. (Refined3C opts ip op fmt i, Monad m, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> (PP ip i -> PP ip i -> PP ip i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i) -> RefinedT m (Refined3 opts ip op fmt i)
- Predicate.Refined3: withRefined3TP :: forall m opts ip op fmt i b proxy. (Monad m, Refined3C opts ip op fmt i, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> (Refined3 opts ip op fmt i -> RefinedT m b) -> RefinedT m b
+ Predicate.Refined3: withRefined3TP :: forall opts ip op fmt i b proxy m. (Monad m, Refined3C opts ip op fmt i, Show (PP ip i), Show i) => proxy '(opts, ip, op, fmt, i) -> i -> (Refined3 opts ip op fmt i -> RefinedT m b) -> RefinedT m b

Files

predicate-typed.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 6b4766366591bfcedbf8b3452314ca1261917f6b3261789d01dca0eebe6b6b8d+-- hash: aa2ab78d68dcddef601cdef424ad1d3c3bb857cb5afc594647e650913558a4a1  name:           predicate-typed-version:        0.7.2.0+version:        0.7.3.0 synopsis:       Predicates, Refinement types and Dsl description:    Please see the README on GitHub at <https://github.com/gbwey/predicate-typed#readme> category:       Data@@ -28,6 +28,27 @@   exposed-modules:       Predicate       Predicate.Core+      Predicate.Data.Char+      Predicate.Data.Condition+      Predicate.Data.DateTime+      Predicate.Data.Either+      Predicate.Data.Enum+      Predicate.Data.Extra+      Predicate.Data.Foldable+      Predicate.Data.Index+      Predicate.Data.IO+      Predicate.Data.Iterator+      Predicate.Data.Json+      Predicate.Data.List+      Predicate.Data.Maybe+      Predicate.Data.Monoid+      Predicate.Data.Numeric+      Predicate.Data.Ordering+      Predicate.Data.ReadShow+      Predicate.Data.Regex+      Predicate.Data.String+      Predicate.Data.These+      Predicate.Data.Tuple       Predicate.Examples.Common       Predicate.Examples.Refined1       Predicate.Examples.Refined2@@ -48,6 +69,7 @@   build-depends:       QuickCheck     , aeson+    , aeson-pretty     , base >=4.7 && <5     , binary     , bytestring@@ -63,6 +85,7 @@     , pretty     , pretty-terminal >=0.1.0.0     , safe+    , string-conversions     , template-haskell     , text     , th-lift@@ -79,6 +102,27 @@   other-modules:       Predicate       Predicate.Core+      Predicate.Data.Char+      Predicate.Data.Condition+      Predicate.Data.DateTime+      Predicate.Data.Either+      Predicate.Data.Enum+      Predicate.Data.Extra+      Predicate.Data.Foldable+      Predicate.Data.Index+      Predicate.Data.IO+      Predicate.Data.Iterator+      Predicate.Data.Json+      Predicate.Data.List+      Predicate.Data.Maybe+      Predicate.Data.Monoid+      Predicate.Data.Numeric+      Predicate.Data.Ordering+      Predicate.Data.ReadShow+      Predicate.Data.Regex+      Predicate.Data.String+      Predicate.Data.These+      Predicate.Data.Tuple       Predicate.Examples.Common       Predicate.Examples.Refined1       Predicate.Examples.Refined2@@ -99,6 +143,7 @@   build-depends:       QuickCheck     , aeson+    , aeson-pretty     , base     , binary     , bytestring@@ -116,6 +161,7 @@     , pretty     , pretty-terminal >=0.1.0.0     , safe+    , string-conversions     , template-haskell     , text     , th-lift@@ -143,6 +189,7 @@   build-depends:       QuickCheck     , aeson+    , aeson-pretty     , base     , binary     , bytestring@@ -160,6 +207,7 @@     , pretty-terminal >=0.1.0.0     , safe     , stm+    , string-conversions     , tasty     , tasty-hunit     , tasty-quickcheck
src/Predicate/Core.hs view
@@ -4,888 +4,2392 @@ {-# OPTIONS -Wincomplete-uni-patterns #-}
 {-# OPTIONS -Wredundant-constraints #-}
 {-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE AllowAmbiguousTypes #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE PolyKinds #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE NoStarIsType #-}
-{- |
-     Dsl for evaluating and displaying type level expressions
--}
-module Predicate.Core (
-
- -- ** basic types
-    I
-  , Id
-  , IdT
-  , W
-  , Msg
-  , Hide
-
-  -- ** display evaluation tree
-  , pan
-  , panv
-  , pa
-  , pu
-  , pab
-  , pub
-  , pav
-  , puv
-  , pl
-  , pz
-  , run
-  , runs
-
-  , P(..)
-
-  -- ** evaluation methods
-  , runPQ
-  , runPQBool
-  , evalBool
-  , evalBoolHide
-  , evalHide
-  , evalQuick
-  , prtTree
-  ) where
-import Predicate.Util
-import GHC.TypeLits (Symbol,Nat,KnownSymbol,KnownNat)
-import Control.Lens ((&), (^.), (.~))
-import Data.Proxy
-import Data.Typeable
-import Data.Kind (Type)
-import Data.These (These(..))
-import Data.Functor.Identity
--- $setup
--- >>> :set -XDataKinds
--- >>> :set -XTypeApplications
--- >>> :set -XTypeOperators
-
--- | This is the core class. Each instance of this class can be combined into a dsl using 'Predicate.Prelude.>>'
-class P p a where
-  type PP (p :: k) a :: Type -- PP is the output type
-  eval :: MonadEval m
-     => proxy p -- ^ proxy for the expression
-     -> POpts  -- ^ display options
-     -> a      -- ^ value
-     -> m (TT (PP p a)) -- ^ returns a tree of results
-
--- | A specialised form of 'eval' that works only on predicates
-evalBool :: ( MonadEval m
-            , P p a
-            , PP p a ~ Bool
-            ) => proxy p
-              -> POpts
-              -> a
-              -> m (TT (PP p a))
-evalBool p opts a = fixBoolT <$> eval p opts a
-
-evalQuick :: forall p i . P p i => i -> Either String (PP p i)
-evalQuick i = getValLRFromTT (runIdentity (eval (Proxy @p) (getOptT @OL) i))
-
--- | identity function
---
--- >>> pz @I 23
--- PresentT 23
-data I
-instance P I a where
-  type PP I a = a
-  eval _ opts a =
-    let msg0 = "I"
-    in pure $ mkNode opts (PresentT a) msg0 []
-
-
--- | identity function that displays the input unlike 'I'
---
--- even more constraints than 'I' so we might need to add explicit type signatures
---
--- >>> pz @Id 23
--- PresentT 23
-data Id
-instance Show a => P Id a where
-  type PP Id a = a
-  eval _ opts a =
-    let msg0 = "Id"
-    in pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
-
-
--- even more constraints than 'Id' so we might need to explicitly add types (Typeable)
--- | identity function that also displays the type information for debugging
---
--- >>> pz @IdT 23
--- PresentT 23
-data IdT
-instance ( Typeable a
-         , Show a
-         ) => P IdT a where
-  type PP IdT a = a
-  eval _ opts a =
-    let msg0 = "IdT(" <> t <> ")"
-        t = showT @a
-    in pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
-
--- | transparent predicate wrapper to make k of kind 'Type' so it can be in a promoted list (cant mix kinds) see 'Predicate.Core.Do'
---
--- >>> pz @'[W 123, Id] 99
--- PresentT [123,99]
---
--- >>> pz @'[W "abc", W "def", Id, Id] "ghi"
--- PresentT ["abc","def","ghi","ghi"]
---
-data W (p :: k)
-instance P p a => P (W p) a where
-  type PP (W p) a = PP p a
-  eval _ = eval (Proxy @(Msg "W " p))
-
--- | add a message to give more context to the evaluation tree
---
--- >>> pan @(Msg "[somemessage] " Id) 999
--- P [somemessage] Id 999
--- PresentT 999
---
--- >>> pan @(Msg Id 999) "info message:"
--- P info message:'999
--- PresentT 999
---
-data Msg prt p
-
-instance (P prt a
-        , PP prt a ~ String
-        , P p a
-        ) => P (Msg prt p) a where
-  type PP (Msg prt p) a = PP p a
-  eval _ opts a = do
-    pp <- eval (Proxy @prt) opts a
-    case getValueLR opts "Msg" pp [] of
-         Left e -> pure e
-         Right msg -> prefixMsg msg <$> eval (Proxy @p) opts a
-
--- | run the expression \'p\' but remove the subtrees
-data Hide p
--- type H p = Hide p -- doesnt work with %   -- unsaturated!
-
-instance P p x => P (Hide p) x where
-  type PP (Hide p) x = PP p x
-  eval _ opts x = do
-      tt <- eval (Proxy @p) opts x
-      pure $ tt & tForest .~ []
-
--- | 'const' () function
---
--- >>> pz @() "Asf"
--- PresentT ()
---
-instance P () a where
-  type PP () a = ()
-  eval _ opts _ =
-    let msg0 = "()"
-    in pure $ mkNode opts (PresentT ()) msg0 []
-
-instance P (Proxy t) a where
-  type PP (Proxy t) a = Proxy t
-  eval _ opts _ =
-    let msg0 = "Proxy"
-    in pure $ mkNode opts (PresentT Proxy) msg0 []
-
--- Start non-Type kinds
------------------------
-
--- | pulls the type level 'Bool' to the value level
---
--- >>> pz @'True "not used"
--- TrueT
---
--- >>> pz @'False ()
--- FalseT
-instance GetBool b => P (b :: Bool) a where
-  type PP b a = Bool
-  eval _ opts _ =
-    let b = getBool @b
-    in pure $ mkNodeB opts b ("'" <> show b) []
-
--- | pulls the type level 'Symbol' to the value level as a 'GHC.Base.String'
---
--- >>> pz @"hello world" ()
--- PresentT "hello world"
-instance KnownSymbol s => P (s :: Symbol) a where
-  type PP s a = String
-  eval _ opts _ =
-    let s = symb @s
-    in pure $ mkNode opts (PresentT s) ("'" <> litL opts ("\"" <> s <> "\"")) []
-
--- | run the predicates in a promoted 2-tuple; similar to 'Control.Arrow.&&&'
---
--- >>> pz @'(Id, 4) "hello"
--- PresentT ("hello",4)
---
-instance ( P p a
-         , P q a
---         , Show (PP p a)
---         , Show (PP q a)
-         ) => P '(p,q) a where
-  type PP '(p,q) a = (PP p a, PP q a)
-  eval _ opts a = do
-    let msg = "'(,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-       Left e -> e
-       Right (p,q,pp,qq) ->
-         mkNode opts (PresentT (p,q)) msg [hh pp, hh qq]
---         mkNode opts (PresentT (p,q)) ("'(" <> showL opts p <> ", " <> showL opts q <> ")") [hh pp, hh qq]
-
--- | run the predicates in a promoted 3-tuple
---
--- >>> pz @'(4, Id, "goodbye") "hello"
--- PresentT (4,"hello","goodbye")
---
--- >>> pan @'( 'True, 'False, 123) True
--- P '(,,)
--- |
--- +- True 'True
--- |
--- +- False 'False
--- |
--- `- P '123
--- PresentT (True,False,123)
---
-instance (P p a
-        , P q a
-        , P r a
-        ) => P '(p,q,r) a where
-  type PP '(p,q,r) a = (PP p a, PP q a, PP r a)
-  eval _ opts a = do
-    let msg = "'(,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-         let hhs0 = [hh pp, hh qq]
-         rr <- eval (Proxy @r) opts a
-         pure $ case getValueLR opts msg rr hhs0 of
-           Left e -> e
-           Right r ->
-             let hhs1 = hhs0 <> [hh rr]
-             in mkNode opts (PresentT (p,q,r)) msg hhs1
-
--- | run the predicates in a promoted 4-tuple
---
--- >>> pz @'(4, Id, "inj", 999) "hello"
--- PresentT (4,"hello","inj",999)
---
-instance (P p a
-        , P q a
-        , P r a
-        , P s a
-        ) => P '(p,q,r,s) a where
-  type PP '(p,q,r,s) a = (PP p a, PP q a, PP r a, PP s a)
-  eval _ opts a = do
-    let msg = "'(,,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs0 = [hh pp, hh qq]
-        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
-        pure $ case lr1 of
-          Left e -> e
-          Right (r,s,rr,ss) ->
-            let hhs1 = hhs0 ++ [hh rr, hh ss]
-            in mkNode opts (PresentT (p,q,r,s)) msg hhs1
-
--- | run the predicates in a promoted 5-tuple
---
--- >>> pz @'(4, Id, "inj", 999, 'LT) "hello"
--- PresentT (4,"hello","inj",999,LT)
---
-instance (P p a
-        , P q a
-        , P r a
-        , P s a
-        , P t a
-        ) => P '(p,q,r,s,t) a where
-  type PP '(p,q,r,s,t) a = (PP p a, PP q a, PP r a, PP s a, PP t a)
-  eval _ opts a = do
-    let msg = "'(,,,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs0 = [hh pp, hh qq]
-        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
-        case lr1 of
-          Left e -> pure e
-          Right (r,s,rr,ss) -> do
-            let hhs1 = hhs0 ++ [hh rr, hh ss]
-            tt <- eval (Proxy @t) opts a
-            pure $ case getValueLR opts msg tt hhs1 of
-              Left e -> e
-              Right t ->
-                let hhs2 = hhs1 <> [hh tt]
-                in mkNode opts (PresentT (p,q,r,s,t)) msg hhs2
-
--- | run the predicates in a promoted 6-tuple
---
--- >>> pz @'(4, Id, "inj", 999, 'LT, 1) "hello"
--- PresentT (4,"hello","inj",999,LT,1)
---
-instance (P p a
-        , P q a
-        , P r a
-        , P s a
-        , P t a
-        , P u a
-        ) => P '(p,q,r,s,t,u) a where
-  type PP '(p,q,r,s,t,u) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a)
-  eval _ opts a = do
-    let msg = "'(,,,,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs0 = [hh pp, hh qq]
-        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
-        case lr1 of
-          Left e -> pure e
-          Right (r,s,rr,ss) -> do
-            let hhs1 = hhs0 ++ [hh rr, hh ss]
-            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
-            pure $ case lr2 of
-              Left e -> e
-              Right (t,u,tt,uu) ->
-                let hhs2 = hhs1 ++ [hh tt, hh uu]
-                in mkNode opts (PresentT (p,q,r,s,t,u)) msg hhs2
-
--- | run the predicates in a promoted 7-tuple
---
--- >>> pz @'(4, Id, "inj", 999, 'LT, 1, 2) "hello"
--- PresentT (4,"hello","inj",999,LT,1,2)
---
-instance (P p a
-        , P q a
-        , P r a
-        , P s a
-        , P t a
-        , P u a
-        , P v a
-        ) => P '(p,q,r,s,t,u,v) a where
-  type PP '(p,q,r,s,t,u,v) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a, PP v a)
-  eval _ opts a = do
-    let msg = "'(,,,,,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs0 = [hh pp, hh qq]
-        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
-        case lr1 of
-          Left e -> pure e
-          Right (r,s,rr,ss) -> do
-            let hhs1 = hhs0 ++ [hh rr, hh ss]
-            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
-            case lr2 of
-              Left e -> pure e
-              Right (t,u,tt,uu) -> do
-                vv <- eval (Proxy @v) opts a
-                let hhs2 = hhs1 ++ [hh tt, hh uu]
-                pure $ case getValueLR opts msg vv hhs2 of
-                  Left e -> e
-                  Right v ->
-                    let hhs3 = hhs2 ++ [hh vv]
-                    in mkNode opts (PresentT (p,q,r,s,t,u,v)) msg hhs3
-
--- | run the predicates in a promoted 8-tuple
---
--- >>> pz @'(4, Id, "inj", 999, 'LT, 1, 2, 3) "hello"
--- PresentT (4,"hello","inj",999,LT,1,2,3)
---
-instance (P p a
-        , P q a
-        , P r a
-        , P s a
-        , P t a
-        , P u a
-        , P v a
-        , P w a
-        ) => P '(p,q,r,s,t,u,v,w) a where
-  type PP '(p,q,r,s,t,u,v,w) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a, PP v a, PP w a)
-  eval _ opts a = do
-    let msg = "'(,,,,,,,)"
-    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs0 = [hh pp, hh qq]
-        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
-        case lr1 of
-          Left e -> pure e
-          Right (r,s,rr,ss) -> do
-            let hhs1 = hhs0 ++ [hh rr, hh ss]
-            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
-            case lr2 of
-              Left e -> pure e
-              Right (t,u,tt,uu) -> do
-                let hhs2 = hhs1 ++ [hh tt, hh uu]
-                lr3 <- runPQ msg (Proxy @v) (Proxy @w) opts a hhs2
-                pure $ case lr3 of
-                  Left e -> e
-                  Right (v,w,vv,ww) ->
-                     let hhs3 = hhs2 ++ [hh vv, hh ww]
-                     in mkNode opts (PresentT (p,q,r,s,t,u,v,w)) msg hhs3
-
-
--- | extracts the value level representation of the promoted 'Ordering'
---
--- >>> pz @'LT "not used"
--- PresentT LT
---
--- >>> pz @'EQ ()
--- PresentT EQ
-instance GetOrdering cmp => P (cmp :: Ordering) a where
-  type PP cmp a = Ordering
-  eval _ opts _a =
-    let cmp = getOrdering @cmp
-        msg = "'" <> show cmp
-    in pure $ mkNode opts (PresentT cmp) msg []
-
--- | extracts the value level representation of the type level 'Nat'
---
--- >>> pz @123 ()
--- PresentT 123
-instance KnownNat n => P (n :: Nat) a where
-  type PP n a = Int
-  eval _ opts _ =
-    let n = nat @n
-    in pure $ mkNode opts (PresentT n) ("'" <> show n) []
-
--- | extracts the value level representation of the type level '()
---
--- >>> pz @'() ()
--- PresentT ()
-instance P '() a where
-  type PP '() a = ()
-  eval _ opts _ = pure $ mkNode opts (PresentT ()) "'()" []
-
--- the type has to be [a] so we still need type PP '[p] a = [PP p a] to keep the types in line
-
--- | extracts the value level representation of the type level '[]
---
--- >>> pz @'[] False
--- PresentT []
-instance P ('[] :: [k]) a where
-  type PP ('[] :: [k]) a = [a]
-  eval _ opts _ = pure $ mkNode opts (PresentT mempty) "'[]" []
-
--- | runs each predicate in turn from the promoted list
---
--- >>> pz @'[1, 2, 3] 999
--- PresentT [1,2,3]
---
--- >>> pz @'[W 1, W 2, W 3, Id] 999
--- PresentT [1,2,3,999]
---
-instance ( Show (PP p a)
-         , Show a
-         , P p a
-         ) => P '[p] a where
-  type PP '[p] a = [PP p a]
-  eval _ opts a = do
-    pp <- eval (Proxy @p) opts a
-    let msg0 = ""
-    pure $ case getValueLR opts msg0 pp [] of
-       Left e -> e
-       Right b -> mkNode opts (PresentT [b]) ("'" <> showL opts [b] <> showVerbose opts " | " a) [hh pp]
-
-instance (Show (PP p a)
-        , Show a
-        , P (p1 ': ps) a
-        , PP (p1 ': ps) a ~ [PP p1 a]
-        , P p a
-        , PP p a ~ PP p1 a
-        ) => P (p ': p1 ': ps) a where
-  type PP (p ': p1 ': ps) a = [PP p a]
-  eval _ opts a = do
-    let msg0 = "'(p':q)"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        qq <- eval (Proxy @(p1 ': ps)) opts a
-        pure $ case getValueLR opts msg0 qq [hh pp] of
-          Left e -> e
-          Right q ->
-            let ret = p:q
-            -- no gap between ' and ret!
-            in mkNode opts (PresentT ret) ("'" <> showL opts ret <> litVerbose opts " " (topMessage pp) <> showVerbose opts " | " a) ([hh pp | isVerbose opts] <> [hh qq])
-
--- | extracts the \'a\' from type level \'Maybe a\' if the value exists
---
--- >>> pz @('Just Id) (Just 123)
--- PresentT 123
---
--- >>> pz @('Just Id) (Just True)
--- PresentT True
---
--- >>> pz @('Just Id) Nothing
--- FailT "'Just found Nothing"
---
-instance (Show (PP p a)
-        , P p a
-        , Show a
-        ) => P ('Just p) (Maybe a) where
-  type PP ('Just p) (Maybe a) = PP p a
-  eval _ opts ma = do
-    let msg0 = "'Just"
-    case ma of
-      Just a -> do
-        pp <- eval (Proxy @p) opts a
-        pure $ case getValueLR opts msg0 pp [] of
-          Left e -> e
-          Right b -> mkNode opts (PresentT b) (show01 opts msg0 b ma) [hh pp]
-      Nothing -> pure $ mkNode opts (FailT (msg0 <> " found Nothing")) "" []
-
--- | expects Nothing otherwise it fails
--- if the value is Nothing then it returns \'Proxy a\' as this provides type information
---
--- >>> pz @'Nothing Nothing
--- PresentT Proxy
---
--- >>> pz @'Nothing (Just True)
--- FailT "'Nothing found Just"
---
-instance P 'Nothing (Maybe a) where
-  type PP 'Nothing (Maybe a) = Proxy a -- () gives us less information
-  eval _ opts ma =
-    let msg0 = "'Nothing"
-    in pure $ case ma of
-         Nothing -> mkNode opts (PresentT Proxy) msg0 []
-         Just _ -> mkNode opts (FailT (msg0 <> " found Just")) "" []
-
--- omitted Show x so we can have less ambiguity
--- | extracts the \'a\' from type level \'Either a b\' if the value exists
---
--- >>> pz @('Left Id) (Left 123)
--- PresentT 123
---
--- >>> pz @('Left Id) (Right "aaa")
--- FailT "'Left found Right"
---
-instance (Show a
-        , Show (PP p a)
-        , P p a
-        ) => P ('Left p) (Either a x) where
-  type PP ('Left p) (Either a x) = PP p a
-  eval _ opts lr =
-    let msg0 = "'Left"
-    in case lr of
-         Right _ -> pure $ mkNode opts (FailT (msg0 <> " found Right")) "" []
-         Left a -> do
-            pp <- eval (Proxy @p) opts a
-            pure $ case getValueLR opts msg0 pp [] of
-                 Left e -> e
-                 Right b -> mkNode opts (_tBool pp) (show01' opts msg0 b "Left " a) [hh pp]
-
--- | extracts the \'b\' from type level \'Either a b\' if the value exists
---
--- >>> pz @('Right Id) (Right 123)
--- PresentT 123
---
--- >>> pz @('Right Id) (Left "aaa")
--- FailT "'Right found Left"
---
-instance (Show a
-        , Show (PP p a)
-        , P p a
-        ) => P ('Right p) (Either x a) where
-  type PP ('Right p) (Either x a) = PP p a
-  eval _ opts lr = do
-    let msg0 = "'Right"
-    case lr of
-         Left _ -> pure $ mkNode opts (FailT (msg0 <> " found Left")) "" []
-         Right a -> do
-            pp <- eval (Proxy @p) opts a
-            pure $ case getValueLR opts msg0 pp [] of
-                 Left e -> e
-                 Right b -> mkNode opts (_tBool pp) (show01' opts msg0 b "Right " a) [hh pp]
-
--- removed Show x: else ambiguity errors in TestPredicate
-
--- | extracts the \'a\' from type level \'These a b\' if the value exists
---
--- >>> pz @('This Id) (This 123)
--- PresentT 123
---
--- >>> pz @('This Id) (That "aaa")
--- FailT "'This found That"
---
--- >>> pz @('This Id) (These 999 "aaa")
--- FailT "'This found These"
---
-instance (Show a
-        , Show (PP p a)
-        , P p a
-        ) => P ('This p) (These a x) where
-  type PP ('This p) (These a x) = PP p a
-  eval _ opts th = do
-    let msg0 = "'This"
-    case th of
-         This a -> do
-            pp <- eval (Proxy @p) opts a
-            pure $ case getValueLR opts msg0 pp [] of
-                 Left e -> e
-                 Right b -> mkNode opts (_tBool pp) (show01' opts msg0 b "This " a) [hh pp]
-         _ -> pure $ mkNode opts (FailT (msg0 <> " found " <> showThese th)) "" []
-
--- | extracts the \'b\' from type level \'These a b\' if the value exists
---
--- >>> pz @('That Id) (That 123)
--- PresentT 123
---
--- >>> pz @('That Id) (This "aaa")
--- FailT "'That found This"
---
--- >>> pz @('That Id) (These 44 "aaa")
--- FailT "'That found These"
---
-instance (Show a
-        , Show (PP p a)
-        , P p a
-        ) => P ('That p) (These x a) where
-  type PP ('That p) (These x a) = PP p a
-  eval _ opts th = do
-    let msg0 = "'That"
-    case th of
-         That a -> do
-            pp <- eval (Proxy @p) opts a
-            pure $ case getValueLR opts msg0 pp [] of
-                 Left e -> e
-                 Right b -> mkNode opts (_tBool pp) (show01' opts msg0 b "That " a) [hh pp]
-         _ -> pure $ mkNode opts (FailT (msg0 <> " found " <> showThese th)) "" []
-
-
--- | extracts the (a,b) from type level 'These a b' if the value exists
---
--- >>> pz @('These Id Id) (These 123 "abc")
--- PresentT (123,"abc")
---
--- >>> pz @('These Id 5) (These 123 "abcde")
--- PresentT (123,5)
---
--- >>> pz @('These Id Id) (This "aaa")
--- FailT "'These found This"
---
--- >>> pz @('These Id Id) (That "aaa")
--- FailT "'These found That"
---
-instance (Show a
-        , Show b
-        , P p a
-        , P q b
-        , Show (PP p a)
-        , Show (PP q b)
-        ) => P ('These p q) (These a b) where
-  type PP ('These p q) (These a b) = (PP p a, PP q b)
-  eval _ opts th = do
-    let msg0 = "'These"
-    case th of
-         These a b -> do
-            pp <- eval (Proxy @p) opts a
-            case getValueLR opts msg0 pp [] of
-               Left e -> pure e
-               Right p -> do
-                 qq <- eval (Proxy @q) opts b
-                 pure $ case getValueLR opts (msg0 <> " q failed p=" <> showL opts p) qq [hh pp] of
-                    Left e -> e
-                    Right q ->
-                      let ret =(p,q)
-                      in  mkNode opts (PresentT ret) (show01 opts msg0 ret (These a b)) [hh pp, hh qq]
-         _ -> pure $ mkNode opts (FailT (msg0 <> " found " <> showThese th)) "" []
-
--- | converts the value to the corresponding 'Proxy'
---
--- >>> pz @'Proxy 'x'
--- PresentT Proxy
---
-instance Show a => P 'Proxy a where
-  type PP 'Proxy a = Proxy a
-  eval _ opts a =
-    let b = Proxy @a
-    in pure $ mkNode opts (PresentT b) ("'Proxy" <> showVerbose opts " | " a) []
-
--- | typelevel 'BoolT'
---
--- >>> pz @'TrueT ()
--- TrueT
---
--- >>> pz @'FalseT ()
--- FalseT
---
--- >>> pz @('PresentT 123) ()
--- PresentT False
---
--- >>> pz @('FailT '[]) ()
--- FailT "'FailT _"
---
-instance GetBoolT x b => P (b :: BoolT x) a where
-  type PP b a = Bool
-  eval _ opts _ = do
-    let ret = getBoolT @x @b
-    pure $ case ret of
-      Left b -> mkNodeB opts b (if b then "'TrueT" else "'FalseT") []
-      Right True -> mkNode opts (PresentT False) "'PresentT _" []
-      Right False -> mkNode opts (FailT "'FailT _") "BoolT" []
-
-pan, panv, pa, pu, pl, pz, pab, pub, pav, puv
-  :: forall p a
-  . ( Show (PP p a)
-    , P p a
-    ) => a
-      -> IO (BoolT (PP p a))
--- | skips the evaluation tree and just displays the end result
-pz = run @OZ @p
--- | same as 'pz' but adds context to the end result
-pl = run @OL @p
--- | displays the evaluation tree in plain text without colors
-pan = run @OAN @p
--- | displays the evaluation tree in plain text without colors and verbose
-panv = run @OANV @p
--- | displays the evaluation tree using colors without background colors
-pa = run @OA @p
--- | displays the evaluation tree using background colors
-pab = run @OAB @p
--- | 'pa' and verbose
-pav = run @OAV @p
--- | display the evaluation tree using unicode and colors
--- @
---   pu @'(Id, "abc", 123) [1..4]
--- @
-pu = run @OU @p
--- | displays the evaluation tree using unicode and colors with background colors
-pub = run @OUB @p
--- | 'pu' and verbose
-puv = run @OUV @p
-
--- | evaluate a typelevel expression (use type applications to pass in the options and the expression)
---
--- >>> run @OZ @Id 123
--- PresentT 123
---
--- >>> run @('OMsg "field1" ':# OL) @('Left Id) (Right 123)
--- field1 >>> Error 'Left found Right
--- FailT "'Left found Right"
---
--- >>> run @(OptTT '[ 'OMsg "test", OU, 'OEmpty, OL, 'OMsg "field2"]) @('FailT '[]) ()
--- test | field2 >>> Error 'FailT _ (BoolT)
--- FailT "'FailT _"
---
-run :: forall opts p a
-        . ( OptTC opts
-          , Show (PP p a)
-          , P p a)
-        => a
-        -> IO (BoolT (PP p a))
-run a = do
-  let opts = getOptT @opts
-  pp <- eval (Proxy @p) opts a
-  let r = pp ^. tBool
-  putStr $ prtTree opts pp
-  return r
-
--- | run expression with multiple options in a list
---
--- >>> runs @'[ OL, 'OMsg "field2"] @'( 'True, 'False) ()
--- field2 >>> Present (True,False) ('(,))
--- PresentT (True,False)
---
--- >>> runs @'[ 'OMsg "test", OU, 'OEmpty, OL, 'OMsg "field2"] @('FailT '[]) ()
--- test | field2 >>> Error 'FailT _ (BoolT)
--- FailT "'FailT _"
---
-runs :: forall optss p a
-        . ( OptTC (OptTT optss)
-          , Show (PP p a)
-          , P p a)
-        => a
-        -> IO (BoolT (PP p a))
-runs = run @(OptTT optss) @p
-
-
-prtTree :: Show x => POpts -> TT x -> String
-prtTree opts pp =
-  let r = pp ^. tBool
-  in case oDebug opts of
-       DZero -> ""
-       DLite ->
-             formatOMsg opts " >>> "
-          <> colorBoolT opts r
-          <> " "
-          <> topMessage pp
-          <> "\n"
-       _ -> formatOMsg opts "\n"
-         <> prtTreePure opts (fromTT pp)
-
-runPQ :: ( P p a
-         , P q a
-         , MonadEval m)
-   => String
-   -> proxy1 p
-   -> proxy2 q
-   -> POpts
-   -> a
-   -> [Holder]
-   -> m (Either (TT x) (PP p a, PP q a, TT (PP p a), TT (PP q a)))
-runPQ msg0 proxyp proxyq opts a hhs = do
-    pp <- eval proxyp opts a
-    case getValueLR opts msg0 pp hhs of
-      Left e -> pure $ Left e
-      Right p -> do
-         qq <- eval proxyq opts a
-         pure $ case getValueLR opts msg0 qq (hhs <> [hh pp]) of
-           Left e -> Left e
-           Right q -> Right (p, q, pp, qq)
-
-runPQBool :: ( P p a
-             , PP p a ~ Bool
-             , P q a
-             , PP q a ~ Bool, MonadEval m)
-   => String
-   -> proxy1 p
-   -> proxy2 q
-   -> POpts
-   -> a
-   -> [Holder]
-   -> m (Either (TT x) (PP p a, PP q a, TT (PP p a), TT (PP q a)))
-runPQBool msg0 proxyp proxyq opts a hhs = do
-    pp <- evalBool proxyp opts a
-    case getValueLR opts msg0 pp hhs of
-      Left e -> pure $ Left e
-      Right p -> do
-         qq <- evalBool proxyq opts a
-         pure $ case getValueLR opts msg0 qq (hhs <> [hh pp]) of
-           Left e -> Left e
-           Right q -> Right (p, q, pp, qq)
-
-evalBoolHide :: forall m p a proxy
-  . (MonadEval m, P p a, PP p a ~ Bool)
-  => proxy p
-  -> POpts
-  -> a
-  -> m (TT (PP p a))
-evalBoolHide _ opts =
-  if isVerbose opts then evalBool (Proxy @p) opts
-  else evalBool (Proxy @(Hide p)) opts
-
-evalHide :: forall m p a proxy
-  . (MonadEval m, P p a)
-  => proxy p
-  -> POpts
-  -> a
-  -> m (TT (PP p a))
-evalHide _ opts =
-  if isVerbose opts then eval (Proxy @p) opts
-  else eval (Proxy @(Hide p)) opts+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     Dsl for evaluating and displaying type level expressions
+-}
+module Predicate.Core (
+
+ -- ** basic types
+    Id
+  , IdT
+  , I
+  , W
+  , Msg
+  , MsgI
+  , Hide
+  , Width
+  , Hole
+  , Unproxy
+  , Len
+  , Length
+  , Map
+  , Do
+  , Pure
+  , Coerce
+  , OneP
+  , type (>>)
+
+  -- ** tree evaluation
+  , pan
+  , panv
+  , pa
+  , pu
+  , pab
+  , pub
+  , pav
+  , puv
+  , pl
+  , pz
+  , run
+  , runs
+
+  , P(..)
+
+  -- ** evaluation methods
+  , runPQ
+  , runPQBool
+  , evalBool
+  , evalBoolHide
+  , evalHide
+  , evalQuick
+
+ -- ** wrap, unwrap expressions
+  , Unwrap
+  , Wrap
+  , Wrap'
+
+ -- ** failure expressions
+  , Fail
+  , Failp
+  , Failt
+  , FailS
+
+ -- ** tuple expressions
+  , Fst
+  , Snd
+  , Thd
+  , L1
+  , L2
+  , L3
+  , L4
+  , L5
+  , L6
+
+  -- ** boolean expressions
+  , type (&&)
+  , type (&&~)
+  , type (||)
+  , type (||~)
+  , type (~>)
+  , Not
+  , Between
+  , All
+  , Any
+  , IdBool
+
+ -- ** miscellaneous
+  , type (<..>)
+  , type (<<)
+  , Swap
+  , SwapC(..)
+  , type ($)
+  , type (&)
+
+  ) where
+import Predicate.Util
+import qualified GHC.TypeLits as GL
+import GHC.TypeLits (Symbol,Nat,KnownSymbol,KnownNat)
+import Control.Lens -- ((&), (^.), (.~))
+import Data.Foldable (toList)
+import Data.Proxy
+import Data.Typeable
+import Data.Kind (Type)
+import Data.These (These(..))
+import Control.Monad
+import Data.List
+import Data.Coerce
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.Time
+
+-- | This is the core class. Each instance of this class can be combined into a dsl using 'Predicate.Core.>>'
+class P p a where
+  type PP (p :: k) a :: Type -- PP is the output type
+  eval :: MonadEval m
+     => proxy p -- ^ proxy for the expression
+     -> POpts  -- ^ display options
+     -> a      -- ^ value
+     -> m (TT (PP p a)) -- ^ returns a tree of results
+
+-- | A specialised form of 'eval' that works only on predicates
+evalBool :: ( MonadEval m
+            , P p a
+            , PP p a ~ Bool
+            ) => proxy p
+              -> POpts
+              -> a
+              -> m (TT (PP p a))
+evalBool p opts a = fixBoolT <$> eval p opts a
+
+evalQuick :: forall p i . P p i => i -> Either String (PP p i)
+evalQuick i = getValLRFromTT (runIdentity (eval (Proxy @p) (getOptT @OL) i))
+
+-- | identity function without show instance of 'Id'
+--
+-- >>> pz @I 23
+-- PresentT 23
+--
+data I
+instance P I a where
+  type PP I a = a
+  eval _ opts a =
+    let msg0 = "I"
+    in pure $ mkNode opts (PresentT a) msg0 []
+
+
+-- | identity function
+--
+-- >>> pz @Id 23
+-- PresentT 23
+--
+data Id
+instance Show a => P Id a where
+  type PP Id a = a
+  eval _ opts a =
+    let msg0 = "Id"
+    in pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | identity function that also displays the type information for debugging
+--
+-- >>> pz @IdT 23
+-- PresentT 23
+data IdT
+instance ( Typeable a
+         , Show a
+         ) => P IdT a where
+  type PP IdT a = a
+  eval _ opts a =
+    let msg0 = "IdT(" <> t <> ")"
+        t = showT @a
+    in pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | transparent predicate wrapper to make k of kind 'Type' so it can be in a promoted list (cant mix kinds) see 'Predicate.Core.Do'
+--
+-- >>> pz @'[W 123, Id] 99
+-- PresentT [123,99]
+--
+-- >>> pz @'[W "abc", W "def", Id, Id] "ghi"
+-- PresentT ["abc","def","ghi","ghi"]
+--
+data W (p :: k)
+instance P p a => P (W p) a where
+  type PP (W p) a = PP p a
+  eval _ = eval (Proxy @(MsgI "W " p))
+
+-- | add a message to give more context to the evaluation tree
+--
+-- >>> pan @(Msg "[somemessage]" Id) 999
+-- P [somemessage] Id 999
+-- PresentT 999
+--
+-- >>> pan @(Msg Id 999) "info message:"
+-- P info message: '999
+-- PresentT 999
+--
+data Msg prt p
+
+instance (P prt a
+        , PP prt a ~ String
+        , P p a
+        ) => P (Msg prt p) a where
+  type PP (Msg prt p) a = PP p a
+  eval _ opts a = do
+    pp <- eval (Proxy @prt) opts a
+    case getValueLR opts "Msg" pp [] of
+         Left e -> pure e
+         Right msg -> prefixMsg (setOtherEffects opts msg <> " ") <$> eval (Proxy @p) opts a
+
+-- | add a message to give more context to the evaluation tree
+--
+-- >>> pan @(MsgI "[somemessage] " Id) 999
+-- P [somemessage] Id 999
+-- PresentT 999
+--
+-- >>> pan @(MsgI Id 999) "info message:"
+-- P info message:'999
+-- PresentT 999
+--
+data MsgI prt p
+
+instance (P prt a
+        , PP prt a ~ String
+        , P p a
+        ) => P (MsgI prt p) a where
+  type PP (MsgI prt p) a = PP p a
+  eval _ opts a = do
+    pp <- eval (Proxy @prt) opts a
+    case getValueLR opts "MsgI" pp [] of
+         Left e -> pure e
+         Right msg -> prefixMsg msg <$> eval (Proxy @p) opts a
+
+-- | run the expression \'p\' but remove the subtrees
+data Hide p
+-- type H p = Hide p -- doesnt work with %   -- unsaturated!
+
+instance P p x => P (Hide p) x where
+  type PP (Hide p) x = PP p x
+  eval _ opts x = do
+      tt <- eval (Proxy @p) opts x
+      pure $ tt & tForest .~ []
+
+data Hole (t :: Type)
+
+-- | Acts as a proxy in this dsl where you can explicitly set the Type.
+--
+--  It is passed around as an argument to help the type checker when needed.
+--
+instance Typeable t => P (Hole t) a where
+  type PP (Hole t) a = t -- can only be Type not Type -> Type (can use Proxy but then we go down the rabbithole)
+  eval _ opts _a =
+    let msg0 = "Hole(" <> showT @t <> ")"
+    in pure $ mkNode opts (FailT msg0) "you probably meant to get access to the type of PP only and not evaluate" []
+
+-- | override the display width for the expression \'p\'
+data Width (n :: Nat) p
+
+instance (KnownNat n
+        , P p a
+        ) => P (Width n p) a where
+  type PP (Width n p) a = PP p a
+  eval _ opts a = do
+    let opts' = opts { oWidth = nat @n }
+    eval (Proxy @p) opts' a
+
+-- | 'const' () function
+--
+-- >>> pz @() "Asf"
+-- PresentT ()
+--
+instance P () a where
+  type PP () a = ()
+  eval _ opts _ =
+    let msg0 = "()"
+    in pure $ mkNode opts (PresentT ()) msg0 []
+
+instance P (Proxy t) a where
+  type PP (Proxy t) a = Proxy t
+  eval _ opts _ =
+    let msg0 = "Proxy"
+    in pure $ mkNode opts (PresentT Proxy) msg0 []
+
+-- Start non-Type kinds
+-----------------------
+
+-- | pulls the type level 'Bool' to the value level
+--
+-- >>> pz @'True "not used"
+-- TrueT
+--
+-- >>> pz @'False ()
+-- FalseT
+instance GetBool b => P (b :: Bool) a where
+  type PP b a = Bool
+  eval _ opts _ =
+    let b = getBool @b
+    in pure $ mkNodeB opts b ("'" <> show b) []
+
+-- | pulls the type level 'GHC.TypeLits.Symbol' to the value level as a 'GHC.Base.String'
+--
+-- >>> pz @"hello world" ()
+-- PresentT "hello world"
+instance KnownSymbol s => P (s :: Symbol) a where
+  type PP s a = String
+  eval _ opts _ =
+    let s = symb @s
+    in pure $ mkNode opts (PresentT s) ("'" <> litL opts ("\"" <> s <> "\"")) []
+
+-- | run the predicates in a promoted 2-tuple; similar to 'Control.Arrow.&&&'
+--
+-- >>> pz @'(Id, 4) "hello"
+-- PresentT ("hello",4)
+--
+instance ( P p a
+         , P q a
+         , Show (PP p a)
+         , Show (PP q a)
+         ) => P '(p,q) a where
+  type PP '(p,q) a = (PP p a, PP q a)
+  eval _ opts a = do
+    let msg = "'(,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+       Left e -> e
+       Right (p,q,pp,qq) ->
+--         mkNode opts (PresentT (p,q)) msg [hh pp, hh qq]
+         mkNode opts (PresentT (p,q)) ("'(" <> showL opts p <> "," <> showL opts q <> ")") [hh pp, hh qq]
+
+-- | run the predicates in a promoted 3-tuple
+--
+-- >>> pz @'(4, Id, "goodbye") "hello"
+-- PresentT (4,"hello","goodbye")
+--
+-- >>> pan @'( 'True, 'False, 123) True
+-- P '(,,)
+-- |
+-- +- True 'True
+-- |
+-- +- False 'False
+-- |
+-- `- P '123
+-- PresentT (True,False,123)
+--
+instance (P p a
+        , P q a
+        , P r a
+        ) => P '(p,q,r) a where
+  type PP '(p,q,r) a = (PP p a, PP q a, PP r a)
+  eval _ opts a = do
+    let msg = "'(,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+         let hhs0 = [hh pp, hh qq]
+         rr <- eval (Proxy @r) opts a
+         pure $ case getValueLR opts msg rr hhs0 of
+           Left e -> e
+           Right r ->
+             let hhs1 = hhs0 <> [hh rr]
+             in mkNode opts (PresentT (p,q,r)) msg hhs1
+
+-- | run the predicates in a promoted 4-tuple
+--
+-- >>> pz @'(4, Id, "inj", 999) "hello"
+-- PresentT (4,"hello","inj",999)
+--
+instance (P p a
+        , P q a
+        , P r a
+        , P s a
+        ) => P '(p,q,r,s) a where
+  type PP '(p,q,r,s) a = (PP p a, PP q a, PP r a, PP s a)
+  eval _ opts a = do
+    let msg = "'(,,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs0 = [hh pp, hh qq]
+        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
+        pure $ case lr1 of
+          Left e -> e
+          Right (r,s,rr,ss) ->
+            let hhs1 = hhs0 ++ [hh rr, hh ss]
+            in mkNode opts (PresentT (p,q,r,s)) msg hhs1
+
+-- | run the predicates in a promoted 5-tuple
+--
+-- >>> pz @'(4, Id, "inj", 999, 'LT) "hello"
+-- PresentT (4,"hello","inj",999,LT)
+--
+instance (P p a
+        , P q a
+        , P r a
+        , P s a
+        , P t a
+        ) => P '(p,q,r,s,t) a where
+  type PP '(p,q,r,s,t) a = (PP p a, PP q a, PP r a, PP s a, PP t a)
+  eval _ opts a = do
+    let msg = "'(,,,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs0 = [hh pp, hh qq]
+        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
+        case lr1 of
+          Left e -> pure e
+          Right (r,s,rr,ss) -> do
+            let hhs1 = hhs0 ++ [hh rr, hh ss]
+            tt <- eval (Proxy @t) opts a
+            pure $ case getValueLR opts msg tt hhs1 of
+              Left e -> e
+              Right t ->
+                let hhs2 = hhs1 <> [hh tt]
+                in mkNode opts (PresentT (p,q,r,s,t)) msg hhs2
+
+-- | run the predicates in a promoted 6-tuple
+--
+-- >>> pz @'(4, Id, "inj", 999, 'LT, 1) "hello"
+-- PresentT (4,"hello","inj",999,LT,1)
+--
+instance (P p a
+        , P q a
+        , P r a
+        , P s a
+        , P t a
+        , P u a
+        ) => P '(p,q,r,s,t,u) a where
+  type PP '(p,q,r,s,t,u) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a)
+  eval _ opts a = do
+    let msg = "'(,,,,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs0 = [hh pp, hh qq]
+        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
+        case lr1 of
+          Left e -> pure e
+          Right (r,s,rr,ss) -> do
+            let hhs1 = hhs0 ++ [hh rr, hh ss]
+            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
+            pure $ case lr2 of
+              Left e -> e
+              Right (t,u,tt,uu) ->
+                let hhs2 = hhs1 ++ [hh tt, hh uu]
+                in mkNode opts (PresentT (p,q,r,s,t,u)) msg hhs2
+
+-- | run the predicates in a promoted 7-tuple
+--
+-- >>> pz @'(4, Id, "inj", 999, 'LT, 1, 2) "hello"
+-- PresentT (4,"hello","inj",999,LT,1,2)
+--
+instance (P p a
+        , P q a
+        , P r a
+        , P s a
+        , P t a
+        , P u a
+        , P v a
+        ) => P '(p,q,r,s,t,u,v) a where
+  type PP '(p,q,r,s,t,u,v) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a, PP v a)
+  eval _ opts a = do
+    let msg = "'(,,,,,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs0 = [hh pp, hh qq]
+        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
+        case lr1 of
+          Left e -> pure e
+          Right (r,s,rr,ss) -> do
+            let hhs1 = hhs0 ++ [hh rr, hh ss]
+            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
+            case lr2 of
+              Left e -> pure e
+              Right (t,u,tt,uu) -> do
+                vv <- eval (Proxy @v) opts a
+                let hhs2 = hhs1 ++ [hh tt, hh uu]
+                pure $ case getValueLR opts msg vv hhs2 of
+                  Left e -> e
+                  Right v ->
+                    let hhs3 = hhs2 ++ [hh vv]
+                    in mkNode opts (PresentT (p,q,r,s,t,u,v)) msg hhs3
+
+-- | run the predicates in a promoted 8-tuple
+--
+-- >>> pz @'(4, Id, "inj", 999, 'LT, 1, 2, 3) "hello"
+-- PresentT (4,"hello","inj",999,LT,1,2,3)
+--
+instance (P p a
+        , P q a
+        , P r a
+        , P s a
+        , P t a
+        , P u a
+        , P v a
+        , P w a
+        ) => P '(p,q,r,s,t,u,v,w) a where
+  type PP '(p,q,r,s,t,u,v,w) a = (PP p a, PP q a, PP r a, PP s a, PP t a, PP u a, PP v a, PP w a)
+  eval _ opts a = do
+    let msg = "'(,,,,,,,)"
+    lr <- runPQ msg (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs0 = [hh pp, hh qq]
+        lr1 <- runPQ msg (Proxy @r) (Proxy @s) opts a hhs0
+        case lr1 of
+          Left e -> pure e
+          Right (r,s,rr,ss) -> do
+            let hhs1 = hhs0 ++ [hh rr, hh ss]
+            lr2 <- runPQ msg (Proxy @t) (Proxy @u) opts a hhs1
+            case lr2 of
+              Left e -> pure e
+              Right (t,u,tt,uu) -> do
+                let hhs2 = hhs1 ++ [hh tt, hh uu]
+                lr3 <- runPQ msg (Proxy @v) (Proxy @w) opts a hhs2
+                pure $ case lr3 of
+                  Left e -> e
+                  Right (v,w,vv,ww) ->
+                     let hhs3 = hhs2 ++ [hh vv, hh ww]
+                     in mkNode opts (PresentT (p,q,r,s,t,u,v,w)) msg hhs3
+
+
+-- | extracts the value level representation of the promoted 'Ordering'
+--
+-- >>> pz @'LT "not used"
+-- PresentT LT
+--
+-- >>> pz @'EQ ()
+-- PresentT EQ
+instance GetOrdering cmp => P (cmp :: Ordering) a where
+  type PP cmp a = Ordering
+  eval _ opts _a =
+    let cmp = getOrdering @cmp
+        msg = "'" <> show cmp
+    in pure $ mkNode opts (PresentT cmp) msg []
+
+-- | extracts the value level representation of the type level 'Nat'
+--
+-- >>> pz @123 ()
+-- PresentT 123
+--
+instance KnownNat n => P (n :: Nat) a where
+  type PP n a = Int
+  eval _ opts _ =
+    let n = nat @n
+    in pure $ mkNode opts (PresentT n) ("'" <> show n) []
+
+-- | extracts the value level representation of the type level '()
+--
+-- >>> pz @'() ()
+-- PresentT ()
+instance P '() a where
+  type PP '() a = ()
+  eval _ opts _ = pure $ mkNode opts (PresentT ()) "'()" []
+
+-- the type has to be [a] so we still need type PP '[p] a = [PP p a] to keep the types in line
+
+-- | extracts the value level representation of the type level '[]
+--
+-- >>> pz @'[] False
+-- PresentT []
+instance P ('[] :: [k]) a where
+  type PP ('[] :: [k]) a = [a]
+  eval _ opts _ = pure $ mkNode opts (PresentT mempty) "'[]" []
+
+-- | runs each predicate in turn from the promoted list
+--
+-- >>> pz @'[1, 2, 3] 999
+-- PresentT [1,2,3]
+--
+-- >>> pz @'[W 1, W 2, W 3, Id] 999
+-- PresentT [1,2,3,999]
+--
+instance ( Show (PP p a)
+         , Show a
+         , P p a
+         ) => P '[p] a where
+  type PP '[p] a = [PP p a]
+  eval _ opts a = do
+    pp <- eval (Proxy @p) opts a
+    let msg0 = ""
+    pure $ case getValueLR opts msg0 pp [] of
+       Left e -> e
+       Right b -> mkNode opts (PresentT [b]) ("'" <> showL opts [b] <> showVerbose opts " | " a) [hh pp]
+
+instance (Show (PP p a)
+        , Show a
+        , P (p1 ': ps) a
+        , PP (p1 ': ps) a ~ [PP p1 a]
+        , P p a
+        , PP p a ~ PP p1 a
+        ) => P (p ': p1 ': ps) a where
+  type PP (p ': p1 ': ps) a = [PP p a]
+  eval _ opts a = do
+    let msg0 = "'(p':q)"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        qq <- eval (Proxy @(p1 ': ps)) opts a
+        pure $ case getValueLR opts msg0 qq [hh pp] of
+          Left e -> e
+          Right q ->
+            let ret = p:q
+            -- no gap between ' and ret!
+            in mkNode opts (PresentT ret) ("'" <> showL opts ret <> litVerbose opts " " (topMessage pp) <> showVerbose opts " | " a) ([hh pp | isVerbose opts] <> [hh qq])
+
+-- | tries to extract @a@ from @Maybe a@ otherwise it fails: similar to 'Data.Maybe.fromJust'
+--
+-- >>> pz @('Just Id) (Just "abc")
+-- PresentT "abc"
+--
+-- >>> pl @('Just Id >> Id) (Just 123)
+-- Present 123 ((>>) 123 | {Id 123})
+-- PresentT 123
+--
+-- >>> pl @('Just Id) (Just [1,2,3])
+-- Present [1,2,3] ('Just [1,2,3] | Just [1,2,3])
+-- PresentT [1,2,3]
+--
+-- >>> pl @('Just Id) (Just 10)
+-- Present 10 ('Just 10 | Just 10)
+-- PresentT 10
+--
+-- >>> pl @('Just Id) Nothing
+-- Error 'Just(empty)
+-- FailT "'Just(empty)"
+--
+-- >>> pz @('Just (Fst Id)) (Just 123,'x')
+-- PresentT 123
+--
+instance (Show a
+        , PP p x ~ Maybe a
+        , P p x
+        ) => P ('Just p) x where
+  type PP ('Just p) x = MaybeT (PP p x)
+  eval _ opts x = do
+    let msg0 = "'Just"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p of
+          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
+          Just d -> mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+-- | expects Nothing otherwise it fails
+--   if the value is Nothing then it returns \'Proxy a\' as this provides type information
+--
+-- >>> pz @'Nothing Nothing
+-- PresentT Proxy
+--
+-- >>> pz @'Nothing (Just True)
+-- FailT "'Nothing found Just"
+--
+instance P 'Nothing (Maybe a) where
+  type PP 'Nothing (Maybe a) = Proxy a -- () gives us less information
+  eval _ opts ma =
+    let msg0 = "'Nothing"
+    in pure $ case ma of
+         Nothing -> mkNode opts (PresentT Proxy) msg0 []
+         Just _ -> mkNode opts (FailT (msg0 <> " found Just")) "" []
+
+-- omitted Show x so we can have less ambiguity
+-- | extracts the \'a\' from type level \'Either a b\' if the value exists
+--
+-- >>> pz @('Left Id) (Left 123)
+-- PresentT 123
+--
+-- >>> pz @('Left (Snd Id)) ('x', Left 123)
+-- PresentT 123
+--
+-- >>> pz @('Left Id) (Right "aaa")
+-- FailT "'Left found Right"
+--
+-- >>> pl @('Left Id) (Left 123)
+-- Present 123 (Left)
+-- PresentT 123
+--
+-- >>> pl @('Left Id) (Right 123)
+-- Error 'Left found Right
+-- FailT "'Left found Right"
+--
+
+instance ( PP p x ~ Either a b
+         , P p x)
+    => P ('Left p) x where
+  type PP ('Left p) x = LeftT (PP p x)
+  eval _ opts x = do
+    let msg0 = "'Left"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p of
+          Left a -> mkNode opts (PresentT a) "Left" [hh pp]
+          Right _b -> mkNode opts (FailT (msg0 <> " found Right")) "" [hh pp]
+
+-- | extracts the \'b\' from type level \'Either a b\' if the value exists
+--
+-- >>> pl @('Right Id) (Right 123)
+-- Present 123 (Right)
+-- PresentT 123
+--
+-- >>> pz @('Right Id >> Snd Id) (Right ('x',123))
+-- PresentT 123
+--
+-- >>> pz @('Right Id) (Left "aaa")
+-- FailT "'Right found Left"
+--
+-- >>> pl @('Right Id) (Left 123)
+-- Error 'Right found Left
+-- FailT "'Right found Left"
+--
+instance ( PP p x ~ Either a b
+         , P p x)
+    => P ('Right p) x where
+  type PP ('Right p) x = RightT (PP p x)
+  eval _ opts x = do
+    let msg0 = "'Right"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p of
+          Left _a -> mkNode opts (FailT (msg0 <> " found Left")) "" [hh pp]
+          Right b -> mkNode opts (PresentT b) "Right" [hh pp]
+
+
+-- removed Show x: else ambiguity errors in TestPredicate
+
+-- | extracts the \'a\' from type level \'These a b\' if the value exists
+--
+-- >>> pl @('This Id) (This 12)
+-- Present 12 (This)
+-- PresentT 12
+--
+-- >>> pz @('This Id) (That "aaa")
+-- FailT "'This found That"
+--
+-- >>> pz @('This Id) (These 999 "aaa")
+-- FailT "'This found These"
+--
+-- >>> pl @('This Id) (That 12)
+-- Error 'This found That
+-- FailT "'This found That"
+--
+
+instance ( PP p x ~ These a b
+         , P p x)
+    => P ('This p) x where
+  type PP ('This p) x = ThisT (PP p x)
+  eval _ opts x = do
+    let msg0 = "'This"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p of
+          This a -> mkNode opts (PresentT a) "This" [hh pp]
+          That _b -> mkNode opts (FailT (msg0 <> " found That")) "" [hh pp]
+          These _a _b -> mkNode opts (FailT (msg0 <> " found These")) "" [hh pp]
+
+-- | extracts the \'b\' from type level \'These a b\' if the value exists
+--
+-- >>> pz @('That Id) (That 123)
+-- PresentT 123
+--
+-- >>> pz @('That Id) (This "aaa")
+-- FailT "'That found This"
+--
+-- >>> pz @('That Id) (These 44 "aaa")
+-- FailT "'That found These"
+--
+
+instance ( PP p x ~ These a b
+         , P p x)
+    => P ('That p) x where
+  type PP ('That p) x = ThatT (PP p x)
+  eval _ opts x = do
+    let msg0 = "'That"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p of
+          This _a -> mkNode opts (FailT (msg0 <> " found This")) "" [hh pp]
+          That b -> mkNode opts (PresentT b) "That" [hh pp]
+          These _a _b -> mkNode opts (FailT (msg0 <> " found These")) "" [hh pp]
+
+
+-- | extracts the (a,b) from type level \'These a b\' if the value exists
+--
+-- >>> pz @('These Id Id) (These 123 "abc")
+-- PresentT (123,"abc")
+--
+-- >>> pz @('These Id 5) (These 123 "abcde")
+-- PresentT (123,5)
+--
+-- >>> pz @('These Id Id) (This "aaa")
+-- FailT "'These found This"
+--
+-- >>> pz @('These Id Id) (That "aaa")
+-- FailT "'These found That"
+--
+instance (Show a
+        , Show b
+        , P p a
+        , P q b
+        , Show (PP p a)
+        , Show (PP q b)
+        ) => P ('These p q) (These a b) where
+  type PP ('These p q) (These a b) = (PP p a, PP q b)
+  eval _ opts th = do
+    let msg0 = "'These"
+    case th of
+         These a b -> do
+            pp <- eval (Proxy @p) opts a
+            case getValueLR opts msg0 pp [] of
+               Left e -> pure e
+               Right p -> do
+                 qq <- eval (Proxy @q) opts b
+                 pure $ case getValueLR opts (msg0 <> " q failed p=" <> showL opts p) qq [hh pp] of
+                    Left e -> e
+                    Right q ->
+                      let ret =(p,q)
+                      in  mkNode opts (PresentT ret) (show01 opts msg0 ret (These a b)) [hh pp, hh qq]
+         _ -> pure $ mkNode opts (FailT (msg0 <> " found " <> showThese th)) "" []
+
+-- | converts the value to the corresponding 'Proxy'
+--
+-- >>> pz @'Proxy 'x'
+-- PresentT Proxy
+--
+instance Show a => P 'Proxy a where
+  type PP 'Proxy a = Proxy a
+  eval _ opts a =
+    let b = Proxy @a
+    in pure $ mkNode opts (PresentT b) ("'Proxy" <> showVerbose opts " | " a) []
+
+-- | typelevel 'BoolT'
+--
+-- >>> pz @'TrueT ()
+-- TrueT
+--
+-- >>> pz @'FalseT ()
+-- FalseT
+--
+-- >>> pz @('PresentT 123) ()
+-- PresentT False
+--
+-- >>> pz @('FailT '[]) ()
+-- FailT "'FailT _"
+--
+instance GetBoolT x b => P (b :: BoolT x) a where
+  type PP b a = Bool
+  eval _ opts _ = do
+    let ret = getBoolT @x @b
+    pure $ case ret of
+      Left b -> mkNodeB opts b (if b then "'TrueT" else "'FalseT") []
+      Right True -> mkNode opts (PresentT False) "'PresentT _" []
+      Right False -> mkNode opts (FailT "'FailT _") "BoolT" []
+
+pan, panv, pa, pu, pl, pz, pab, pub, pav, puv
+  :: forall p a
+  . ( Show (PP p a)
+    , P p a
+    ) => a
+      -> IO (BoolT (PP p a))
+-- | skips the evaluation tree and just displays the end result
+pz = run @OZ @p
+-- | same as 'pz' but adds context to the end result
+pl = run @OL @p
+-- | displays the evaluation tree in plain text without colors
+pan = run @OAN @p
+-- | displays the evaluation tree in plain text without colors and verbose
+panv = run @OANV @p
+-- | displays the evaluation tree using colors without background colors
+pa = run @OA @p
+-- | displays the evaluation tree using background colors
+pab = run @OAB @p
+-- | 'pa' and verbose
+pav = run @OAV @p
+-- | display the evaluation tree using unicode and colors
+-- @
+--   pu @'(Id, "abc", 123) [1..4]
+-- @
+pu = run @OU @p
+-- | displays the evaluation tree using unicode and colors with background colors
+pub = run @OUB @p
+-- | 'pu' and verbose
+puv = run @OUV @p
+
+-- | evaluate a typelevel expression (use type applications to pass in the options and the expression)
+--
+-- >>> run @OZ @Id 123
+-- PresentT 123
+--
+-- >>> run @('OMsg "field1" ':# OL) @('Left Id) (Right 123)
+-- field1 >>> Error 'Left found Right
+-- FailT "'Left found Right"
+--
+-- >>> run @(OptTT '[ 'OMsg "test", OU, 'OEmpty, OL, 'OMsg "field2"]) @('FailT '[]) ()
+-- test | field2 >>> Error 'FailT _ (BoolT)
+-- FailT "'FailT _"
+--
+run :: forall opts p a
+        . ( OptTC opts
+          , Show (PP p a)
+          , P p a)
+        => a
+        -> IO (BoolT (PP p a))
+run a = do
+  let opts = getOptT @opts
+  pp <- eval (Proxy @p) opts a
+  let r = pp ^. tBool
+  putStr $ prtTree opts pp
+  return r
+
+-- | run expression with multiple options in a list
+--
+-- >>> runs @'[ OL, 'OMsg "field2"] @'( 'True, 'False) ()
+-- field2 >>> Present (True,False) ('(True,False))
+-- PresentT (True,False)
+--
+-- >>> runs @'[ 'OMsg "test", OU, 'OEmpty, OL, 'OMsg "field2"] @('FailT '[]) ()
+-- test | field2 >>> Error 'FailT _ (BoolT)
+-- FailT "'FailT _"
+--
+runs :: forall optss p a
+        . ( OptTC (OptTT optss)
+          , Show (PP p a)
+          , P p a)
+        => a
+        -> IO (BoolT (PP p a))
+runs = run @(OptTT optss) @p
+
+-- | convenience method to evaluate two expressions using the same input and return the results
+runPQ :: ( P p a
+         , P q a
+         , MonadEval m)
+   => String
+   -> proxy1 p
+   -> proxy2 q
+   -> POpts
+   -> a
+   -> [Holder]
+   -> m (Either (TT x) (PP p a, PP q a, TT (PP p a), TT (PP q a)))
+runPQ msg0 proxyp proxyq opts a hhs = do
+    pp <- eval proxyp opts a
+    case getValueLR opts msg0 pp hhs of
+      Left e -> pure $ Left e
+      Right p -> do
+         qq <- eval proxyq opts a
+         pure $ case getValueLR opts msg0 qq (hhs <> [hh pp]) of
+           Left e -> Left e
+           Right q -> Right (p, q, pp, qq)
+
+-- | convenience method to evaluate two boolean expressions using the same input and return the results
+runPQBool :: ( P p a
+             , PP p a ~ Bool
+             , P q a
+             , PP q a ~ Bool, MonadEval m)
+   => String
+   -> proxy1 p
+   -> proxy2 q
+   -> POpts
+   -> a
+   -> [Holder]
+   -> m (Either (TT x) (PP p a, PP q a, TT (PP p a), TT (PP q a)))
+runPQBool msg0 proxyp proxyq opts a hhs = do
+    pp <- evalBool proxyp opts a
+    case getValueLR opts msg0 pp hhs of
+      Left e -> pure $ Left e
+      Right p -> do
+         qq <- evalBool proxyq opts a
+         pure $ case getValueLR opts msg0 qq (hhs <> [hh pp]) of
+           Left e -> Left e
+           Right q -> Right (p, q, pp, qq)
+
+-- | evaluate a boolean expressions but hide the results unless verbose
+evalBoolHide :: forall p a m
+  . (MonadEval m, P p a, PP p a ~ Bool)
+  => POpts
+  -> a
+  -> m (TT (PP p a))
+evalBoolHide opts =
+  if isVerbose opts then evalBool (Proxy @p) opts
+  else evalBool (Proxy @(Hide p)) opts
+
+-- | evaluate a expressions but hide the results unless verbose
+evalHide :: forall p a m
+  . (MonadEval m, P p a)
+  => POpts
+  -> a
+  -> m (TT (PP p a))
+evalHide opts =
+  if isVerbose opts then eval (Proxy @p) opts
+  else eval (Proxy @(Hide p)) opts
+
+
+-- advantage of (>>) over 'Do [k] is we can use different kinds for (>>) without having to wrap with 'W'
+
+-- | compose expressions
+--
+-- >>> pz @(Fst Id >> Snd Id) ((11,12),'x')
+-- PresentT 12
+--
+data p >> q
+infixr 1 >>
+
+instance (Show (PP p a)
+        , Show (PP q (PP p a))
+        , P p a
+        , P q (PP p a)
+        ) => P (p >> q) a where
+  type PP (p >> q) a = PP q (PP p a)
+  eval _ opts a = do
+    let msg0 = "(>>)"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts "(>>) lhs failed" pp [] of
+      Left e -> pure e
+      Right p -> do
+        qq <- eval (Proxy @q) opts p
+        pure $ case getValueLR opts (show p <> " (>>) rhs failed") qq [hh pp] of
+          Left e -> e
+          Right q -> mkNode opts (_tBool qq) (lit01 opts msg0 q "" (topMessageEgregious qq)) [hh pp, hh qq]
+
+-- | flipped version of 'Predicate.Core.>>'
+data p << q
+type LeftArrowsT p q = q >> p
+infixr 1 <<
+
+instance P (LeftArrowsT p q) x => P (p << q) x where
+  type PP (p << q) x = PP (LeftArrowsT p q) x
+  eval _ = eval (Proxy @(LeftArrowsT p q))
+
+-- bearbeiten! only used by >>
+topMessageEgregious :: TT a -> String
+topMessageEgregious pp = innermost (pp ^. tString)
+  where innermost = ('{':) . reverse . ('}':) . takeWhile (/='{') . dropWhile (=='}') . reverse
+
+-- | unwraps a value (see '_Wrapped'')
+--
+-- >>> pz @(Unwrap Id) (SG.Sum (-13))
+-- PresentT (-13)
+--
+-- >>> pl @(Unwrap Id >> '(Id, 'True)) (SG.Sum 13)
+-- Present (13,True) ((>>) (13,True) | {'(13,True)})
+-- PresentT (13,True)
+--
+data Unwrap p
+
+instance (PP p x ~ s
+        , P p x
+        , Show s
+        , Show (Unwrapped s)
+        , Wrapped s
+        ) => P (Unwrap p) x where
+  type PP (Unwrap p) x = Unwrapped (PP p x)
+  eval _ opts x = do
+    let msg0 = "Unwrap"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = p ^. _Wrapped'
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+data Wrap' t p
+
+instance (Show (PP p x)
+        , P p x
+        , Unwrapped (PP s x) ~ PP p x
+        , Wrapped (PP s x)
+        , Show (PP s x)
+        ) => P (Wrap' s p) x where
+  type PP (Wrap' s p) x = PP s x
+  eval _ opts x = do
+    let msg0 = "Wrap"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = p ^. _Unwrapped'
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+-- | wraps a value (see '_Wrapped'' and '_Unwrapped'')
+--
+-- >>> pz @(Wrap (SG.Sum _) Id) (-13)
+-- PresentT (Sum {getSum = -13})
+--
+-- >>> pz @(Wrap SG.Any (Ge 4)) 13
+-- PresentT (Any {getAny = True})
+--
+-- >>> import Data.List.NonEmpty (NonEmpty(..))
+-- >>> pz @(Wrap (NonEmpty _) (Uncons >> 'Just Id)) "abcd"
+-- PresentT ('a' :| "bcd")
+--
+-- >>> pl @(Wrap (SG.Sum _) Id) 13
+-- Present Sum {getSum = 13} (Wrap Sum {getSum = 13} | 13)
+-- PresentT (Sum {getSum = 13})
+--
+-- >>> pl @(Wrap (SG.Sum _) Id >> STimes 4 Id) 13
+-- Present Sum {getSum = 52} ((>>) Sum {getSum = 52} | {getSum = 13})
+-- PresentT (Sum {getSum = 52})
+--
+-- >>> pl @(Wrap _ 13 <> Id) (SG.Sum @Int 12)
+-- Present Sum {getSum = 25} (Sum {getSum = 13} <> Sum {getSum = 12} = Sum {getSum = 25})
+-- PresentT (Sum {getSum = 25})
+--
+
+data Wrap (t :: Type) p
+type WrapT (t :: Type) p = Wrap' (Hole t) p
+
+instance P (WrapT t p) x => P (Wrap t p) x where
+  type PP (Wrap t p) x = PP (WrapT t p) x
+  eval _ = eval (Proxy @(WrapT t p))
+
+
+-- | used for type inference
+data Unproxy
+
+instance Typeable a => P Unproxy (Proxy (a :: Type)) where
+  type PP Unproxy (Proxy a) = a
+  eval _ opts _a =
+    let msg0 = "Unproxy(" <> showT @a <> ")"
+    in pure $ mkNode opts (FailT msg0) "you probably meant to get access to the type of PP only and not evaluate" []
+
+-- | similar to 'length'
+--
+-- >>> pz @Len [10,4,5,12,3,4]
+-- PresentT 6
+--
+-- >>> pz @Len []
+-- PresentT 0
+--
+data Len
+instance ( Show a
+         , as ~ [a]
+         ) => P Len as where
+  type PP Len as = Int
+  eval _ opts as =
+    let msg0 = "Len"
+        n = length as
+    in pure $ mkNode opts (PresentT n) (show01 opts msg0 n as) []
+
+-- | similar to 'length' for 'Foldable' instances
+--
+-- >>> pz @(Length Id) (Left "aa")
+-- PresentT 0
+--
+-- >>> pz @(Length Id) (Right "aa")
+-- PresentT 1
+--
+-- >>> pz @(Length Right') (Right "abcd")
+-- PresentT 4
+--
+-- >>> pz @(Length (Thd (Snd Id))) (True,(23,'x',[10,9,1,3,4,2]))
+-- PresentT 6
+--
+data Length p
+
+instance (PP p x ~ t a
+        , P p x
+        , Show (t a)
+        , Foldable t) => P (Length p) x where
+  type PP (Length p) x = Int
+  eval _ opts x = do
+    let msg0 = "Length"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+            let n = length p
+            in mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
+
+-- | 'not' function
+--
+-- >>> pz @(Not Id) False
+-- TrueT
+--
+-- >>> pz @(Not Id) True
+-- FalseT
+--
+-- >>> pz @(Not (Fst Id)) (True,22)
+-- FalseT
+--
+-- >>> pl @(Not (Lt 3)) 13
+-- True (Not (13 < 3))
+-- TrueT
+--
+-- >>> pl @(Not 'True) ()
+-- False (Not ('True))
+-- FalseT
+--
+data Not p
+
+instance ( PP p x ~ Bool
+         , P p x
+         ) => P (Not p) x where
+  type PP (Not p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Not"
+    pp <- evalBool (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = not p
+        in mkNodeB opts b (msg0 <> litVerbose opts " " (topMessage pp)) [hh pp]
+
+-- | 'id' function on a boolean
+--
+-- >>> pz @(IdBool Id) False
+-- FalseT
+--
+-- >>> pz @(IdBool Id) True
+-- TrueT
+--
+-- >>> pz @(IdBool (Fst Id)) (True,22)
+-- TrueT
+--
+-- >>> pl @(IdBool (Lt 3)) 13
+-- False (IdBool (13 < 3))
+-- FalseT
+--
+data IdBool p
+
+instance ( PP p x ~ Bool
+         , P p x
+         ) => P (IdBool p) x where
+  type PP (IdBool p) x = Bool
+  eval _ opts x = do
+    let msg0 = "IdBool"
+    pp <- evalBool (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = p
+        in mkNodeB opts b (msg0 <> litVerbose opts " " (topMessage pp)) [hh pp]
+
+-- | Fails the computation with a message but allows you to set the output type
+--
+-- >>> pz @(Failt Int (PrintF "value=%03d" Id)) 99
+-- FailT "value=099"
+--
+-- >>> pz @('False || (Fail 'True "failed")) (99,"somedata")
+-- FailT "failed"
+--
+-- >>> pz @('False || (Fail (Hole Bool) "failed")) (99,"somedata")
+-- FailT "failed"
+--
+-- >>> pz @('False || (Fail (Hole _) "failed")) (99,"somedata")
+-- FailT "failed"
+--
+data Fail t prt
+
+instance (P prt a
+        , PP prt a ~ String
+        ) => P (Fail t prt) a where
+  type PP (Fail t prt) a = PP t a
+  eval _ opts a = do
+    let msg0 = "Fail"
+    pp <- eval (Proxy @prt) opts a
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right s -> mkNode opts (FailT s) (msg0 <> " " <> s) [hh pp | isVerbose opts]
+
+-- | Fails the computation with a message for simple failures: doesnt preserve types
+--
+-- >>> pz @(FailS (PrintT "value=%03d string=%s" Id)) (99,"somedata")
+-- FailT "value=099 string=somedata"
+--
+data FailS p
+instance P (Fail I p) x => P (FailS p) x where
+  type PP (FailS p) x = PP (Fail I p) x
+  eval _ = eval (Proxy @(Fail I p))
+
+-- | Fails the computation with a message (wraps the type in 'Hole')
+--
+-- >>> pz @(Failt Int (PrintF "value=%03d" Id)) 99
+-- FailT "value=099"
+--
+data Failt (t :: Type) p
+instance P (Fail (Hole t) p) x => P (Failt t p) x where
+  type PP (Failt t p) x = PP (Fail (Hole t) p) x
+  eval _ = eval (Proxy @(Fail (Hole t) p))
+
+-- | Fails the computation with a message where the input value is a Proxy
+--
+-- >>> pz @(Ix 3 (Failp "oops")) "abcd"
+-- PresentT 'd'
+--
+-- >>> pz @(Ix 3 (Failp "oops")) "abc"
+-- FailT "oops"
+--
+data Failp p
+instance P (Fail Unproxy p) x => P (Failp p) x where
+  type PP (Failp p) x = PP (Fail Unproxy p) x
+  eval _ = eval (Proxy @(Fail Unproxy p))
+
+-- | gets the singleton value from a foldable
+--
+-- >>> pl @(OneP Id) [10..15]
+-- Error OneP 6 elements (expected one element)
+-- FailT "OneP 6 elements"
+--
+-- >>> pl @(OneP Id) [10]
+-- Present 10 (OneP)
+-- PresentT 10
+--
+-- >>> pl @(OneP Id) []
+-- Error OneP empty (expected one element)
+-- FailT "OneP empty"
+--
+-- >>> pl @(OneP Id) (Just 10)
+-- Present 10 (OneP)
+-- PresentT 10
+--
+-- >>> pl @(OneP Id) Nothing
+-- Error OneP empty (expected one element)
+-- FailT "OneP empty"
+--
+-- >>> pl @(OneP Id) [12]
+-- Present 12 (OneP)
+-- PresentT 12
+--
+-- >>> pl @(OneP Id) [1..5]
+-- Error OneP 5 elements (expected one element)
+-- FailT "OneP 5 elements"
+--
+-- >>> pl @(OneP Id) ([] ::[()])
+-- Error OneP empty (expected one element)
+-- FailT "OneP empty"
+--
+
+data OneP p
+instance (Foldable t
+        , PP p x ~ t a
+        , P p x
+        ) => P (OneP p) x where
+  type PP (OneP p) x = ExtractAFromTA (PP p x)
+  eval _ opts x = do
+    let msg0 = "OneP"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p -> case toList p of
+                   [] -> mkNode opts (FailT (msg0 <> " empty")) "expected one element" [hh pp]
+                   [a] -> mkNode opts (PresentT a) msg0 [hh pp]
+                   as -> let n = length as
+                         in mkNode opts (FailT (msg0 <> " " <> show n <> " elements")) "expected one element" [hh pp]
+
+--type OneP = Guard "expected list of length 1" (Len == 1) >> Head Id
+--type OneP = Guard (PrintF "expected list of length 1 but found length=%d" Len) (Len == 1) >> Head Id
+
+-- | A predicate that determines if the value is between \'p\' and \'q\'
+--
+-- >>> pz @(Between 5 8 Len) [1,2,3,4,5,5,7]
+-- TrueT
+--
+-- >>> pl @(Between 5 8 Id) 9
+-- False (9 <= 8)
+-- FalseT
+--
+-- >>> pl @(Between (Fst Id >> Fst Id) (Fst Id >> Snd Id) (Snd Id)) ((1,4),3)
+-- True (1 <= 3 <= 4)
+-- TrueT
+--
+-- >>> pl @(Between (Fst Id >> Fst Id) (Fst Id >> Snd Id) (Snd Id)) ((1,4),10)
+-- False (10 <= 4)
+-- FalseT
+--
+data Between p q r -- reify as it is used a lot! nicer specific messages at the top level!
+
+instance (Ord (PP p x)
+       , Show (PP p x)
+       , PP r x ~ PP p x
+       , PP r x ~ PP q x
+       , P p x
+       , P q x
+       , P r x
+       ) => P (Between p q r) x where
+  type PP (Between p q r) x = Bool
+  eval _ opts x = do
+    let msg0 = "Between"
+    rr <- eval (Proxy @r) opts x
+    case getValueLR opts msg0 rr [] of
+      Left e -> pure e
+      Right r -> do
+        lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x [hh rr]
+        pure $ case lr of
+          Left e -> e
+          Right (p,q,pp,qq) ->
+            let hhs = [hh rr, hh pp, hh qq]
+            in if p <= r && r <= q then mkNodeB opts True (showL opts p <> " <= " <> showL opts r <> " <= " <> showL opts q) hhs
+               else if p > r then mkNodeB opts False (showL opts p <> " <= " <> showL opts r) hhs
+               else mkNodeB opts False (showL opts r <> " <= " <> showL opts q) hhs
+
+
+-- | A operator predicate that determines if the value is between \'p\' and \'q\'
+--
+-- >>> pz @(5 <..> 8) 6
+-- TrueT
+--
+-- >>> pz @(10 % 4 <..> 40 % 5) 4
+-- TrueT
+--
+-- >>> pz @(10 % 4 <..> 40 % 5) 33
+-- FalseT
+--
+data p <..> q
+infix 4 <..>
+
+type BetweenT p q = Between p q Id
+
+instance P (BetweenT p q) x => P (p <..> q) x where
+  type PP (p <..> q) x = PP (BetweenT p q) x
+  eval _ = evalBool (Proxy @(BetweenT p q))
+
+-- | similar to 'all'
+--
+-- >>> pl @(All (Between 1 8 Id) Id) [7,3,4,1,2,9,0,1]
+-- False (All(8) i=5 (9 <= 8))
+-- FalseT
+--
+-- >>> pz @(All Odd Id) [1,5,11,5,3]
+-- TrueT
+--
+-- >>> pz @(All Odd Id) []
+-- TrueT
+--
+-- >>> run @'OANV @(All Even Id) [1,5,11,5,3]
+-- False All(5) i=0 (1 == 0)
+-- |
+-- +- P Id [1,5,11,5,3]
+-- |
+-- +- False i=0: 1 == 0
+-- |  |
+-- |  +- P 1 `mod` 2 = 1
+-- |  |  |
+-- |  |  +- P I
+-- |  |  |
+-- |  |  `- P '2
+-- |  |
+-- |  `- P '0
+-- |
+-- +- False i=1: 1 == 0
+-- |  |
+-- |  +- P 5 `mod` 2 = 1
+-- |  |  |
+-- |  |  +- P I
+-- |  |  |
+-- |  |  `- P '2
+-- |  |
+-- |  `- P '0
+-- |
+-- +- False i=2: 1 == 0
+-- |  |
+-- |  +- P 11 `mod` 2 = 1
+-- |  |  |
+-- |  |  +- P I
+-- |  |  |
+-- |  |  `- P '2
+-- |  |
+-- |  `- P '0
+-- |
+-- +- False i=3: 1 == 0
+-- |  |
+-- |  +- P 5 `mod` 2 = 1
+-- |  |  |
+-- |  |  +- P I
+-- |  |  |
+-- |  |  `- P '2
+-- |  |
+-- |  `- P '0
+-- |
+-- `- False i=4: 1 == 0
+--    |
+--    +- P 3 `mod` 2 = 1
+--    |  |
+--    |  +- P I
+--    |  |
+--    |  `- P '2
+--    |
+--    `- P '0
+-- FalseT
+--
+-- >>> pl @(All (Gt 3) (Fst Id)) ([10,12,3,5],"ss")
+-- False (All(4) i=2 (3 > 3))
+-- FalseT
+--
+-- >>> pl @(All (Lt 3) Id) [1::Int .. 10]
+-- False (All(10) i=2 (3 < 3))
+-- FalseT
+--
+data All p q
+
+instance (P p a
+        , PP p a ~ Bool
+        , PP q x ~ f a
+        , P q x
+        , Show a
+        , Foldable f
+        ) => P (All p q) x where
+  type PP (All p q) x = Bool
+  eval _ opts x = do
+    let msg0 = "All"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () -> do
+            ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide @p opts a) [0::Int ..] (toList q)
+            pure $ case splitAndAlign opts msg0 ts of
+                 Left e -> e
+                 Right abcs ->
+                   let hhs = hh qq : map (hh . fixit) ts
+                       msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
+                   in case find (not . view _1) abcs of
+                        Nothing -> mkNodeB opts True msg1 hhs
+                        Just (_,(i,_),tt) ->
+                          mkNodeB opts False (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
+
+-- | similar to 'any'
+--
+-- >>> pl @(Any Even Id) [1,5,11,5,3]
+-- False (Any(5))
+-- FalseT
+--
+-- >>> pl @(Any Even Id) [1,5,112,5,3]
+-- True (Any(5) i=2 (0 == 0))
+-- TrueT
+--
+-- >>> pz @(Any Even Id) []
+-- FalseT
+--
+-- >>> pl @(Any (Gt 3) (Fst Id)) ([10,12,3,5],"ss")
+-- True (Any(4) i=0 (10 > 3))
+-- TrueT
+--
+-- >>> pl @(Any (Same 2) Id) [1,4,5]
+-- False (Any(3))
+-- FalseT
+--
+-- >>> pl @(Any (Same 2) Id) [1,4,5,2,1]
+-- True (Any(5) i=3 (2 == 2))
+-- TrueT
+--
+data Any p q
+
+instance (P p a
+        , PP p a ~ Bool
+        , PP q x ~ f a
+        , P q x
+        , Show a
+        , Foldable f
+        ) => P (Any p q) x where
+  type PP (Any p q) x = Bool
+  eval _ opts x = do
+    let msg0 = "Any"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () -> do
+            ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide @p opts a) [0::Int ..] (toList q)
+            pure $ case splitAndAlign opts msg0 ts of
+                 Left e -> e
+                 Right abcs ->
+                   let hhs = hh qq : map (hh . fixit) ts
+                       msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
+                   in case find (view _1) abcs of
+                        Nothing -> mkNodeB opts False msg1 hhs
+                        Just (_,(i,_),tt) ->
+                          mkNodeB opts True (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
+
+-- | similar to 'fst'
+--
+-- >>> pz @(Fst Id) (10,"Abc")
+-- PresentT 10
+--
+-- >>> pz @(Fst Id) (10,"Abc",'x')
+-- PresentT 10
+--
+-- >>> pz @(Fst Id) (10,"Abc",'x',False)
+-- PresentT 10
+--
+-- >>> pl @(Fst Id) (99,'a',False,1.3)
+-- Present 99 (Fst 99 | (99,'a',False,1.3))
+-- PresentT 99
+--
+data Fst p
+
+instance (Show (ExtractL1T (PP p x))
+        , ExtractL1C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (Fst p) x where
+  type PP (Fst p) x = ExtractL1T (PP p x)
+  eval _ opts x = do
+    let msg0 = "Fst"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL1C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data L1 p
+type L1T p = Fst p
+
+instance P (L1T p) x => P (L1 p) x where
+  type PP (L1 p) x = PP (L1T p) x
+  eval _ = eval (Proxy @(L1T p))
+
+class ExtractL1C tp where
+  type ExtractL1T tp
+  extractL1C :: tp -> ExtractL1T tp
+instance ExtractL1C (a,b) where
+  type ExtractL1T (a,b) = a
+  extractL1C (a,_) = a
+instance ExtractL1C (a,b,c) where
+  type ExtractL1T (a,b,c) = a
+  extractL1C (a,_,_) = a
+instance ExtractL1C (a,b,c,d) where
+  type ExtractL1T (a,b,c,d) = a
+  extractL1C (a,_,_,_) = a
+instance ExtractL1C (a,b,c,d,e) where
+  type ExtractL1T (a,b,c,d,e) = a
+  extractL1C (a,_,_,_,_) = a
+instance ExtractL1C (a,b,c,d,e,f) where
+  type ExtractL1T (a,b,c,d,e,f) = a
+  extractL1C (a,_,_,_,_,_) = a
+
+-- | similar to 'snd'
+--
+-- >>> pz @(Snd Id) (10,"Abc")
+-- PresentT "Abc"
+--
+-- >>> pz @(Snd Id) (10,"Abc",True)
+-- PresentT "Abc"
+--
+-- >>> pl @(Snd Id) (99,'a',False,1.3)
+-- Present 'a' (Snd 'a' | (99,'a',False,1.3))
+-- PresentT 'a'
+--
+data Snd p
+
+instance (Show (ExtractL2T (PP p x))
+        , ExtractL2C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (Snd p) x where
+  type PP (Snd p) x = ExtractL2T (PP p x)
+  eval _ opts x = do
+    let msg0 = "Snd"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL2C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data L2 p
+type L2T p = Snd p
+
+instance P (L2T p) x => P (L2 p) x where
+  type PP (L2 p) x = PP (L2T p) x
+  eval _ = eval (Proxy @(L2T p))
+
+class ExtractL2C tp where
+  type ExtractL2T tp
+  extractL2C :: tp -> ExtractL2T tp
+instance ExtractL2C (a,b) where
+  type ExtractL2T (a,b) = b
+  extractL2C (_,b) = b
+instance ExtractL2C (a,b,c) where
+  type ExtractL2T (a,b,c) = b
+  extractL2C (_,b,_) = b
+instance ExtractL2C (a,b,c,d) where
+  type ExtractL2T (a,b,c,d) = b
+  extractL2C (_,b,_,_) = b
+instance ExtractL2C (a,b,c,d,e) where
+  type ExtractL2T (a,b,c,d,e) = b
+  extractL2C (_,b,_,_,_) = b
+instance ExtractL2C (a,b,c,d,e,f) where
+  type ExtractL2T (a,b,c,d,e,f) = b
+  extractL2C (_,b,_,_,_,_) = b
+
+-- | similar to 3rd element in a n-tuple
+--
+-- >>> pz @(Thd Id) (10,"Abc",133)
+-- PresentT 133
+--
+-- >>> pz @(Thd Id) (10,"Abc",133,True)
+-- PresentT 133
+--
+-- >>> pl @(Thd Id) (99,'a',False,1.3)
+-- Present False (Thd False | (99,'a',False,1.3))
+-- PresentT False
+--
+data Thd p
+
+instance (Show (ExtractL3T (PP p x))
+        , ExtractL3C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (Thd p) x where
+  type PP (Thd p) x = ExtractL3T (PP p x)
+  eval _ opts x = do
+    let msg0 = "Thd"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL3C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data L3 p
+type L3T p = Thd p
+
+instance P (L3T p) x => P (L3 p) x where
+  type PP (L3 p) x = PP (L3T p) x
+  eval _ = eval (Proxy @(L3T p))
+
+class ExtractL3C tp where
+  type ExtractL3T tp
+  extractL3C :: tp -> ExtractL3T tp
+instance ExtractL3C (a,b) where
+  type ExtractL3T (a,b) = GL.TypeError ('GL.Text "Thd doesn't work for 2-tuples")
+  extractL3C _ = errorInProgram "Thd doesn't work for 2-tuples"
+instance ExtractL3C (a,b,c) where
+  type ExtractL3T (a,b,c) = c
+  extractL3C (_,_,c) = c
+instance ExtractL3C (a,b,c,d) where
+  type ExtractL3T (a,b,c,d) = c
+  extractL3C (_,_,c,_) = c
+instance ExtractL3C (a,b,c,d,e) where
+  type ExtractL3T (a,b,c,d,e) = c
+  extractL3C (_,_,c,_,_) = c
+instance ExtractL3C (a,b,c,d,e,f) where
+  type ExtractL3T (a,b,c,d,e,f) = c
+  extractL3C (_,_,c,_,_,_) = c
+
+-- | similar to 4th element in a n-tuple
+--
+-- >>> pz @(L4 Id) (10,"Abc",'x',True)
+-- PresentT True
+--
+-- >>> pz @(L4 (Fst (Snd Id))) ('x',((10,"Abc",'x',999),"aa",1),9)
+-- PresentT 999
+--
+-- >>> pl @(L4 Id) (99,'a',False,"someval")
+-- Present "someval" (L4 "someval" | (99,'a',False,"someval"))
+-- PresentT "someval"
+--
+data L4 p
+
+instance (Show (ExtractL4T (PP p x))
+        , ExtractL4C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (L4 p) x where
+  type PP (L4 p) x = ExtractL4T (PP p x)
+  eval _ opts x = do
+    let msg0 = "L4"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL4C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+class ExtractL4C tp where
+  type ExtractL4T tp
+  extractL4C :: tp -> ExtractL4T tp
+instance ExtractL4C (a,b) where
+  type ExtractL4T (a,b) = GL.TypeError ('GL.Text "L4 doesn't work for 2-tuples")
+  extractL4C _ = errorInProgram "L4 doesn't work for 2-tuples"
+instance ExtractL4C (a,b,c) where
+  type ExtractL4T (a,b,c) = GL.TypeError ('GL.Text "L4 doesn't work for 3-tuples")
+  extractL4C _ = errorInProgram "L4 doesn't work for 3-tuples"
+instance ExtractL4C (a,b,c,d) where
+  type ExtractL4T (a,b,c,d) = d
+  extractL4C (_,_,_,d) = d
+instance ExtractL4C (a,b,c,d,e) where
+  type ExtractL4T (a,b,c,d,e) = d
+  extractL4C (_,_,_,d,_) = d
+instance ExtractL4C (a,b,c,d,e,f) where
+  type ExtractL4T (a,b,c,d,e,f) = d
+  extractL4C (_,_,_,d,_,_) = d
+
+-- | similar to 5th element in a n-tuple
+--
+-- >>> pz @(L5 Id) (10,"Abc",'x',True,1)
+-- PresentT 1
+--
+data L5 p
+
+instance (Show (ExtractL5T (PP p x))
+        , ExtractL5C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (L5 p) x where
+  type PP (L5 p) x = ExtractL5T (PP p x)
+  eval _ opts x = do
+    let msg0 = "L5"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL5C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+class ExtractL5C tp where
+  type ExtractL5T tp
+  extractL5C :: tp -> ExtractL5T tp
+instance ExtractL5C (a,b) where
+  type ExtractL5T (a,b) = GL.TypeError ('GL.Text "L5 doesn't work for 2-tuples")
+  extractL5C _ = errorInProgram "L5 doesn't work for 2-tuples"
+instance ExtractL5C (a,b,c) where
+  type ExtractL5T (a,b,c) = GL.TypeError ('GL.Text "L5 doesn't work for 3-tuples")
+  extractL5C _ = errorInProgram "L5 doesn't work for 3-tuples"
+instance ExtractL5C (a,b,c,d) where
+  type ExtractL5T (a,b,c,d) = GL.TypeError ('GL.Text "L5 doesn't work for 4-tuples")
+  extractL5C _ = errorInProgram "L5 doesn't work for 4-tuples"
+instance ExtractL5C (a,b,c,d,e) where
+  type ExtractL5T (a,b,c,d,e) = e
+  extractL5C (_,_,_,_,e) = e
+instance ExtractL5C (a,b,c,d,e,f) where
+  type ExtractL5T (a,b,c,d,e,f) = e
+  extractL5C (_,_,_,_,e,_) = e
+
+
+-- | similar to 6th element in a n-tuple
+--
+-- >>> pz @(L6 Id) (10,"Abc",'x',True,1,99)
+-- PresentT 99
+--
+data L6 p
+
+instance (Show (ExtractL6T (PP p x))
+        , ExtractL6C (PP p x)
+        , P p x
+        , Show (PP p x)
+        ) => P (L6 p) x where
+  type PP (L6 p) x = ExtractL6T (PP p x)
+  eval _ opts x = do
+    let msg0 = "L6"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = extractL6C p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+class ExtractL6C tp where
+  type ExtractL6T tp
+  extractL6C :: tp -> ExtractL6T tp
+instance ExtractL6C (a,b) where
+  type ExtractL6T (a,b) = GL.TypeError ('GL.Text "L6 doesn't work for 2-tuples")
+  extractL6C _ = errorInProgram "L6 doesn't work for 2-tuples"
+instance ExtractL6C (a,b,c) where
+  type ExtractL6T (a,b,c) = GL.TypeError ('GL.Text "L6 doesn't work for 3-tuples")
+  extractL6C _ = errorInProgram "L6 doesn't work for 3-tuples"
+instance ExtractL6C (a,b,c,d) where
+  type ExtractL6T (a,b,c,d) = GL.TypeError ('GL.Text "L6 doesn't work for 4-tuples")
+  extractL6C _ = errorInProgram "L6 doesn't work for 4-tuples"
+instance ExtractL6C (a,b,c,d,e) where
+  type ExtractL6T (a,b,c,d,e) = GL.TypeError ('GL.Text "L6 doesn't work for 5-tuples")
+  extractL6C _ = errorInProgram "L6 doesn't work for 5-tuples"
+instance ExtractL6C (a,b,c,d,e,f) where
+  type ExtractL6T (a,b,c,d,e,f) = f
+  extractL6C (_,_,_,_,_,f) = f
+
+-- | applies \'p\' to the first and second slot of an n-tuple
+--
+-- >>> pl @(Both Len (Fst Id)) (("abc",[10..17],1,2,3),True)
+-- Present (3,8) (Both)
+-- PresentT (3,8)
+--
+-- >>> pl @(Both (Pred Id) $ Fst Id) ((12,'z',[10..17]),True)
+-- Present (11,'y') (Both)
+-- PresentT (11,'y')
+--
+-- >>> pl @(Both (Succ Id) Id) (4,'a')
+-- Present (5,'b') (Both)
+-- PresentT (5,'b')
+--
+-- >>> pl @(Both Len (Fst Id)) (("abc",[10..17]),True)
+-- Present (3,8) (Both)
+-- PresentT (3,8)
+--
+-- >>> pl @(Both (ReadP Day Id) Id) ("1999-01-01","2001-02-12")
+-- Present (1999-01-01,2001-02-12) (Both)
+-- PresentT (1999-01-01,2001-02-12)
+--
+data Both p q
+instance ( ExtractL1C (PP q x)
+         , ExtractL2C (PP q x)
+         , P p (ExtractL1T (PP q x))
+         , P p (ExtractL2T (PP q x))
+         , P q x
+   ) => P (Both p q) x where
+  type PP (Both p q) x = (PP p (ExtractL1T (PP q x)), PP p (ExtractL2T (PP q x)))
+  eval _ opts x = do
+    let msg0 = "Both"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q -> do
+        let (a,a') = (extractL1C q, extractL2C q)
+        pp <- eval (Proxy @p) opts a
+        case getValueLR opts msg0 pp [hh qq] of
+          Left e -> pure e
+          Right b -> do
+            pp' <- eval (Proxy @p) opts a'
+            pure $ case getValueLR opts msg0 pp' [hh qq, hh pp] of
+              Left e -> e
+              Right b' ->
+                mkNode opts (PresentT (b,b')) msg0 [hh qq, hh pp, hh pp']
+
+-- | similar to 'map'
+--
+-- >>> pz @(Map (Pred Id) Id) [1..5]
+-- PresentT [0,1,2,3,4]
+--
+data Map p q
+
+instance (Show (PP p a)
+        , P p a
+        , PP q x ~ f a
+        , P q x
+        , Show a
+        , Show (f a)
+        , Foldable f
+        ) => P (Map p q) x where
+  type PP (Map p q) x = [PP p (ExtractAFromTA (PP q x))]
+  eval _ opts x = do
+    let msg0 = "Map"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q -> do
+        ts <- zipWithM (\i a -> ((i, a),) <$> evalHide @p opts a) [0::Int ..] (toList q)
+        pure $ case splitAndAlign opts msg0 ts of
+             Left e -> e
+             Right abcs ->
+               let vals = map (view _1) abcs
+               in mkNode opts (PresentT vals) (show01 opts msg0 vals q) (hh qq : map (hh . fixit) ts)
+
+-- | processes a type level list predicates running each in sequence: see 'Predicate.>>'
+--
+-- >>> pz @(Do [Pred Id, ShowP Id, Id &&& Len]) 9876543
+-- PresentT ("9876542",7)
+--
+-- >>> pz @(Do '[W 123, W "xyz", Len &&& Id, Pred Id *** Id<>Id]) ()
+-- PresentT (2,"xyzxyz")
+--
+-- >>> pl @(Do '[Succ Id,Id,ShowP Id,Ones Id,Map (ReadBase Int 8 Id) Id]) 1239
+-- Present [1,2,4,0] ((>>) [1,2,4,0] | {Map [1,2,4,0] | ["1","2","4","0"]})
+-- PresentT [1,2,4,0]
+--
+-- >>> pl @(Do '[Pred Id,Id,ShowP Id,Ones Id,Map (ReadBase Int 8 Id) Id]) 1239
+-- Error invalid base 8 (1238 (>>) rhs failed)
+-- FailT "invalid base 8"
+--
+-- >>> pl @(Do '[4,5,6]) ()
+-- Present 6 ((>>) 6 | {'6})
+-- PresentT 6
+--
+-- >>> pl @(Do '["abc", "Def", "ggg", "hhhhh"]) ()
+-- Present "hhhhh" ((>>) "hhhhh" | {'"hhhhh"})
+-- PresentT "hhhhh"
+--
+-- >>> pl @(Do '[ 'LT, 'EQ, 'GT ]) ()
+-- Present GT ((>>) GT | {'GT})
+-- PresentT GT
+--
+-- >>> pl @(Do '[4 % 4,22 % 1 ,12 -% 4]) ()
+-- Present (-3) % 1 ((>>) (-3) % 1 | {Negate (-3) % 1 | 3 % 1})
+-- PresentT ((-3) % 1)
+--
+-- >>> pl @(Do '[ W ('PresentT I), W 'FalseT, Not Id]) False
+-- True ((>>) True | {Not (Id False)})
+-- TrueT
+--
+-- >>> pl @(Do '[W ('PresentT Id), W 'FalseT]) True -- have to wrap them cos BoolT a vs BoolT Bool ie different types
+-- False ((>>) False | {W 'FalseT})
+-- FalseT
+--
+-- >>> pl @(Do '[1,2,3]) ()
+-- Present 3 ((>>) 3 | {'3})
+-- PresentT 3
+--
+
+data Do (ps :: [k])
+
+instance (P (DoExpandT ps) a) => P (Do ps) a where
+  type PP (Do ps) a = PP (DoExpandT ps) a
+  eval _ = eval (Proxy @(DoExpandT ps))
+
+type family DoExpandT (ps :: [k]) :: Type where
+  DoExpandT '[] = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
+  DoExpandT '[p] = Id >> p -- need this else fails cos 1 is nat and would mean that the result is nat not Type!
+  -- if p >> Id then turns TrueT to PresentT True
+  DoExpandT (p ': p1 ': ps) = p >> DoExpandT (p1 ': ps)
+
+-- | similar to 'Prelude.&&'
+--
+-- >>> pz @(Fst Id && Snd Id) (True, True)
+-- TrueT
+--
+-- >>> pz @(Id > 15 && Id < 17) 16
+-- TrueT
+--
+-- >>> pz @(Id > 15 && Id < 17) 30
+-- FalseT
+--
+-- >>> pz @(Fst Id && (Length (Snd Id) >= 4)) (True,[11,12,13,14])
+-- TrueT
+--
+-- >>> pz @(Fst Id && (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
+-- FalseT
+--
+data p && q
+infixr 3 &&
+
+instance (P p a
+        , P q a
+        , PP p a ~ Bool
+        , PP q a ~ Bool
+        ) => P (p && q) a where
+  type PP (p && q) a = Bool
+  eval _ opts a = do
+    let msg0 = "&&"
+    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let zz = case (p,q) of
+                  (True, True) -> ""
+                  (False, True) -> topMessage pp
+                  (True, False) -> topMessage qq
+                  (False, False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+        in mkNodeB opts (p&&q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh pp, hh qq]
+
+-- | short circuit version of boolean And
+--
+-- >>> pl @(Id > 10 &&~ Failt _ "ss") 9
+-- False (False &&~ _ | (9 > 10))
+-- FalseT
+--
+-- >>> pl @(Id > 10 &&~ Id == 12) 11
+-- False (True &&~ False | (11 == 12))
+-- FalseT
+--
+-- >>> pl @(Id > 10 &&~ Id == 11) 11
+-- True (True &&~ True)
+-- TrueT
+--
+data p &&~ q
+infixr 3 &&~
+
+instance (P p a
+        , P q a
+        , PP p a ~ Bool
+        , PP q a ~ Bool
+        ) => P (p &&~ q) a where
+  type PP (p &&~ q) a = Bool
+  eval _ opts a = do
+    let msg0 = "&&~"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right False ->
+        pure $ mkNodeB opts False ("False " <> msg0 <> " _" <> litVerbose opts " | " (topMessage pp)) [hh pp]
+      Right True -> do
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg0 qq [hh pp] of
+          Left e -> e
+          Right q ->
+            let zz = if q then ""
+                     else " | " <> topMessage qq
+            in mkNodeB opts q ("True " <> msg0 <> " " <> showL opts q <> litVerbose opts "" zz) [hh pp, hh qq]
+
+-- | similar to 'Prelude.||'
+--
+-- >>> pz @(Fst Id || (Length (Snd Id) >= 4)) (False,[11,12,13,14])
+-- TrueT
+--
+-- >>> pz @(Not (Fst Id) || (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
+-- FalseT
+--
+data p || q
+infixr 2 ||
+
+instance (P p a
+        , P q a
+        , PP p a ~ Bool
+        , PP q a ~ Bool
+        ) => P (p || q) a where
+  type PP (p || q) a = Bool
+  eval _ opts a = do
+    let msg0 = "||"
+    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let zz = case (p,q) of
+                  (False,False) -> " | " <> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+                  _ -> ""
+        in mkNodeB opts (p||q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> zz) [hh pp, hh qq]
+
+-- | short circuit version of boolean Or
+--
+-- >>> pl @(Id > 10 ||~ Failt _ "ss") 11
+-- True (True ||~ _ | (11 > 10))
+-- TrueT
+--
+-- >>> pz @(Id > 10 ||~ Id == 9) 9
+-- TrueT
+--
+-- >>> pl @(Id > 10 ||~ Id > 9) 9
+-- False (False ||~ False | (9 > 10) ||~ (9 > 9))
+-- FalseT
+--
+data p ||~ q
+infixr 2 ||~
+
+instance (P p a
+        , P q a
+        , PP p a ~ Bool
+        , PP q a ~ Bool
+        ) => P (p ||~ q) a where
+  type PP (p ||~ q) a = Bool
+  eval _ opts a = do
+    let msg0 = "||~"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right False -> do
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg0 qq [hh pp] of
+          Left e -> e
+          Right q ->
+            let zz = if q then ""
+                     else " | " <> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+            in mkNodeB opts q ("False " <> msg0 <> " " <> showL opts q <> litVerbose opts "" zz) [hh pp, hh qq]
+      Right True ->
+        pure $ mkNodeB opts True ("True " <> msg0 <> " _" <> litVerbose opts " | " (topMessage pp)) [hh pp]
+
+-- | boolean implication
+--
+-- >>> pz @(Fst Id ~> (Length (Snd Id) >= 4)) (True,[11,12,13,14])
+-- TrueT
+--
+-- >>> pz @(Fst Id ~> (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
+-- FalseT
+--
+-- >>> pz @(Fst Id ~> (Length (Snd Id) == 4)) (False,[12,11,12,13,14])
+-- TrueT
+--
+-- >>> pz @(Fst Id ~> (Length (Snd Id) >= 4)) (False,[11,12,13,14])
+-- TrueT
+--
+data p ~> q
+infixr 1 ~>
+
+instance (P p a
+        , P q a
+        , PP p a ~ Bool
+        , PP q a ~ Bool
+        ) => P (p ~> q) a where
+  type PP (p ~> q) a = Bool
+  eval _ opts a = do
+    let msg0 = "~>"
+    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let zz = case (p,q) of
+                  (True,False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+                  _ -> ""
+        in mkNodeB opts (p~>q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh pp, hh qq]
+
+
+-- | swaps using 'SwapC'
+--
+-- >>> pz @Swap (Left 123)
+-- PresentT (Right 123)
+--
+-- >>> pz @Swap (Right 123)
+-- PresentT (Left 123)
+--
+-- >>> pz @Swap (These 'x' 123)
+-- PresentT (These 123 'x')
+--
+-- >>> pz @Swap (This 'x')
+-- PresentT (That 'x')
+--
+-- >>> pz @Swap (That 123)
+-- PresentT (This 123)
+--
+-- >>> pz @Swap (123,'x')
+-- PresentT ('x',123)
+--
+-- >>> pz @Swap (Left "abc")
+-- PresentT (Right "abc")
+--
+-- >>> pz @Swap (Right 123)
+-- PresentT (Left 123)
+--
+-- >>> pl @Swap (Right "asfd")
+-- Present Left "asfd" (Swap Left "asfd" | Right "asfd")
+-- PresentT (Left "asfd")
+--
+-- >>> pl @Swap (12,"asfd")
+-- Present ("asfd",12) (Swap ("asfd",12) | (12,"asfd"))
+-- PresentT ("asfd",12)
+--
+
+data Swap
+
+class Bifunctor p => SwapC p where -- (p :: Type -> Type -> Type) where
+  swapC :: p a b -> p b a
+instance SwapC Either where
+  swapC (Left a) = Right a
+  swapC (Right a) = Left a
+instance SwapC These where
+  swapC (This a) = That a
+  swapC (That b) = This b
+  swapC (These a b) = These b a
+instance SwapC (,) where
+  swapC (a,b) = (b,a)
+
+instance (Show (p a b)
+        , SwapC p
+        , Show (p b a)
+        ) => P Swap (p a b) where
+  type PP Swap (p a b) = p b a
+  eval _ opts pabx =
+    let msg0 = "Swap"
+        d = swapC pabx
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabx) []
+
+-- | like 'GHC.Base.$' for expressions
+--
+-- >>> pl @(Fst $ Snd $ Id) ((1,2),(3,4))
+-- Present 3 (Fst 3 | (3,4))
+-- PresentT 3
+--
+-- >>> pl @((<=) 4 $ Fst $ Snd $ Id) ((1,2),(3,4))
+-- False (4 <= 3)
+-- FalseT
+--
+data (p :: k -> k1) $ (q :: k)
+infixr 0 $
+
+instance P (p q) a => P (p $ q) a where
+  type PP (p $ q) a = PP (p q) a
+  eval _  = eval (Proxy @(p q))
+
+-- | similar to 'Control.Lens.&'
+--
+-- >>> pl @(Id & Fst & Singleton & Length) (13,"xyzw")
+-- Present 1 (Length 1 | [13])
+-- PresentT 1
+--
+-- >>> pl @(2 & (&&&) "abc") ()
+-- Present ("abc",2) (W '("abc",2))
+-- PresentT ("abc",2)
+--
+-- >>> pl @(2 & '(,) "abc") ()
+-- Present ("abc",2) ('("abc",2))
+-- PresentT ("abc",2)
+--
+-- >>> pl @('(,) 4 $ '(,) 7 $ "aa") ()
+-- Present (4,(7,"aa")) ('(4,(7,"aa")))
+-- PresentT (4,(7,"aa"))
+--
+-- >>> pl @(Thd $ Snd $ Fst Id) ((1,("W",9,'a')),(3,4))
+-- Present 'a' (Thd 'a' | ("W",9,'a'))
+-- PresentT 'a'
+--
+data (q :: k) & (p :: k -> k1)
+infixl 1 &
+
+instance P (p q) a => P (q & p) a where
+  type PP (q & p) a = PP (p q) a
+  eval _ = eval (Proxy @(p q))
+
+-- | similar to 'pure'
+--
+-- >>> pz @(Pure Maybe Id) 4
+-- PresentT (Just 4)
+--
+-- >>> pz @(Pure [] Id) 4
+-- PresentT [4]
+--
+-- >>> pz @(Pure (Either String) (Fst Id)) (13,True)
+-- PresentT (Right 13)
+--
+-- >>> pl @(Pure Maybe Id) 'x'
+-- Present Just 'x' (Pure Just 'x' | 'x')
+-- PresentT (Just 'x')
+--
+-- >>> pl @(Pure (Either _) Id) 'x'
+-- Present Right 'x' (Pure Right 'x' | 'x')
+-- PresentT (Right 'x')
+--
+-- >>> pl @(Pure (Either _) Id >> Swap) 'x'
+-- Present Left 'x' ((>>) Left 'x' | {Swap Left 'x' | Right 'x'})
+-- PresentT (Left 'x')
+--
+-- >>> pl @(Pure (Either ()) Id >> Swap) 'x'
+-- Present Left 'x' ((>>) Left 'x' | {Swap Left 'x' | Right 'x'})
+-- PresentT (Left 'x')
+--
+-- >>> pl @(Pure (Either String) Id >> Swap) 123
+-- Present Left 123 ((>>) Left 123 | {Swap Left 123 | Right 123})
+-- PresentT (Left 123)
+--
+data Pure (t :: Type -> Type) p
+instance (P p x
+        , Show (PP p x)
+        , Show (t (PP p x))
+        , Applicative t
+        ) => P (Pure t p) x where
+  type PP (Pure t p) x = t (PP p x)
+  eval _ opts x = do
+    let msg0 = "Pure"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right a ->
+        let b = pure a
+        in mkNode opts (PresentT b) (show01 opts msg0 b a) [hh pp]
+
+-- | similar to 'coerce'
+--
+-- >>> pz @(Coerce (SG.Sum Integer)) (Identity (-13))
+-- PresentT (Sum {getSum = -13})
+--
+-- >>> pl @(Coerce SG.Any) True
+-- Present Any {getAny = True} (Coerce Any {getAny = True} | True)
+-- PresentT (Any {getAny = True})
+--
+-- >>> pl @(Coerce Bool) (SG.Any True)
+-- Present True (Coerce True | Any {getAny = True})
+-- PresentT True
+--
+data Coerce (t :: k)
+
+instance (Show a
+        , Show t
+        , Coercible t a
+        ) => P (Coerce t) a where
+  type PP (Coerce t) a = t
+  eval _ opts a =
+    let msg0 = "Coerce"
+        d = a ^. coerced
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d a) []
+
+
+ src/Predicate/Data/Char.hs view
@@ -0,0 +1,472 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted character functions
+-}
+module Predicate.Data.Char (
+ -- ** constructor
+    Char1
+
+ -- ** character predicates
+  , IsLower
+  , IsUpper
+  , IsDigit
+  , IsSpace
+  , IsPunctuation
+  , IsControl
+  , IsHexDigit
+  , IsOctDigit
+  , IsSeparator
+  , IsLatin1
+
+ -- ** string predicates
+  , IsLowerAll
+  , IsUpperAll
+  , IsDigitAll
+  , IsSpaceAll
+  , IsPunctuationAll
+  , IsControlAll
+  , IsHexDigitAll
+  , IsOctDigitAll
+  , IsSeparatorAll
+  , IsLatin1All
+ -- ** change case
+  , ToTitle
+  , ToUpper
+  , ToLower
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Control.Lens hiding (iall)
+import qualified Data.Text.Lens as DTL
+import GHC.TypeLits (Symbol, KnownSymbol)
+import qualified GHC.TypeLits as GL
+import Data.Proxy
+import Data.Char
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+
+-- | extracts the first character from a non empty 'GHC.TypeLits.Symbol'
+--
+-- >>> pz @(Char1 "aBc") ()
+-- PresentT 'a'
+--
+data Char1 (s :: Symbol)  -- gets the first char from the Symbol [requires that Symbol is not empty]
+instance ( KnownSymbol s
+         , GL.CmpSymbol s "" ~ 'GT
+         ) => P (Char1 s) a where
+  type PP (Char1 s) a = Char
+  eval _ opts _ =
+     case symb @s of
+       [] -> errorInProgram "Char1: found empty Symbol/string"
+       c:_ -> pure $ mkNode opts (PresentT c) ("Char1 " <> showL opts c) []
+
+
+-- | a predicate for determining if a character belongs to the given character set
+--
+-- >>> pz @(Map '(IsControl, IsLatin1, IsHexDigit, IsOctDigit, IsDigit, IsPunctuation, IsSeparator, IsSpace) Id) "abc134"
+-- PresentT [(False,True,True,False,False,False,False,False),(False,True,True,False,False,False,False,False),(False,True,True,False,False,False,False,False),(False,True,True,True,True,False,False,False),(False,True,True,True,True,False,False,False),(False,True,True,True,True,False,False,False)]
+--
+data IsCharSet (cs :: CharSet)
+
+instance ( x ~ Char
+         , GetCharSet cs
+         ) => P (IsCharSet cs) x where
+  type PP (IsCharSet cs) x = Bool
+  eval _ opts c =
+    let msg0 = "Is" ++ drop 1 (show cs)
+        (cs,f) = getCharSet @cs
+        b = f c
+    in pure $ mkNodeB opts b (msg0 <> showVerbose opts " | " [c]) []
+
+-- | predicate similar to 'Data.Char.isLower'
+--
+-- >>> pz @IsLower 'X'
+-- FalseT
+--
+-- >>> pz @IsLower '1'
+-- FalseT
+--
+-- >>> pz @IsLower 'a'
+-- TrueT
+--
+
+data IsLower
+type IsLowerT = IsCharSet 'CLower
+
+instance P IsLowerT x => P IsLower x where
+  type PP IsLower x = PP IsLowerT x
+  eval _ = evalBool (Proxy @IsLowerT)
+
+-- | predicate similar to 'Data.Char.isUpper'
+--
+data IsUpper
+type IsUpperT = IsCharSet 'CUpper
+
+instance P IsUpperT x => P IsUpper x where
+  type PP IsUpper x = PP IsUpperT x
+  eval _ = evalBool (Proxy @IsUpperT)
+
+-- | predicate similar to 'Data.Char.isDigit'
+--
+-- >>> pz @IsDigit 'g'
+-- FalseT
+--
+-- >>> pz @IsDigit '9'
+-- TrueT
+--
+data IsDigit
+type IsDigitT = IsCharSet 'CNumber
+instance P IsDigitT x => P IsDigit x where
+  type PP IsDigit x = Bool
+  eval _ = evalBool (Proxy @IsDigitT)
+
+-- | predicate similar to 'Data.Char.isSpace'
+--
+-- >>> pz @IsSpace '\t'
+-- TrueT
+--
+-- >>> pz @IsSpace ' '
+-- TrueT
+--
+-- >>> pz @IsSpace 'x'
+-- FalseT
+--
+data IsSpace
+type IsSpaceT = IsCharSet 'CSpace
+instance P IsSpaceT x => P IsSpace x where
+  type PP IsSpace x = Bool
+  eval _ = evalBool (Proxy @IsSpaceT)
+
+-- | predicate similar to 'Data.Char.isPunctuation'
+--
+data IsPunctuation
+type IsPunctuationT = IsCharSet 'CPunctuation
+instance P IsPunctuationT x => P IsPunctuation x where
+  type PP IsPunctuation x = Bool
+  eval _ = evalBool (Proxy @IsPunctuationT)
+
+-- | predicate similar to 'Data.Char.isControl'
+--
+data IsControl
+type IsControlT = IsCharSet 'CControl
+instance P IsControlT x => P IsControl x where
+  type PP IsControl x = Bool
+  eval _ = evalBool (Proxy @IsControlT)
+
+-- | predicate similar to 'Data.Char.isHexDigit'
+--
+-- >>> pz @IsHexDigit 'A'
+-- TrueT
+--
+-- >>> pz @IsHexDigit 'g'
+-- FalseT
+--
+data IsHexDigit
+type IsHexDigitT = IsCharSet 'CHexDigit
+instance P IsHexDigitT x => P IsHexDigit x where
+  type PP IsHexDigit x = Bool
+  eval _ = evalBool (Proxy @IsHexDigitT)
+
+-- | predicate similar to 'Data.Char.isOctDigit'
+--
+data IsOctDigit
+type IsOctDigitT = IsCharSet 'COctDigit
+instance P IsOctDigitT x => P IsOctDigit x where
+  type PP IsOctDigit x = Bool
+  eval _ = evalBool (Proxy @IsOctDigitT)
+
+-- | predicate similar to 'Data.Char.isSeparator'
+--
+data IsSeparator
+type IsSeparatorT = IsCharSet 'CSeparator
+instance P IsSeparatorT x => P IsSeparator x where
+  type PP IsSeparator x = Bool
+  eval _ = evalBool (Proxy @IsSeparatorT)
+
+-- | predicate similar to 'Data.Char.isLatin1'
+--
+data IsLatin1
+type IsLatin1T = IsCharSet 'CLatin1
+instance P IsLatin1T x => P IsLatin1 x where
+  type PP IsLatin1 x = Bool
+  eval _ = evalBool (Proxy @IsLatin1T)
+
+
+-- | a predicate for determining if a string 'Data.Text.IsText' belongs to the given character set
+--
+-- >>> pl @('Just Uncons >> IsUpper &* IsLowerAll) "AbcdE"
+-- False ((>>) False | {True (&*) False | (IsLowerAll | "bcdE")})
+-- FalseT
+--
+-- >>> pl @('Just Uncons >> IsUpper &* IsLowerAll) "Abcde"
+-- True ((>>) True | {True (&*) True})
+-- TrueT
+--
+-- >>> pl @('Just Uncons >> IsUpper &* IsLowerAll) "xbcde"
+-- False ((>>) False | {False (&*) True | (IsUpper | "x")})
+-- FalseT
+--
+-- >>> pl @('Just Uncons >> IsUpper &* IsLowerAll) "X"
+-- True ((>>) True | {True (&*) True})
+-- TrueT
+--
+-- >>> pz @( '(IsControlAll, IsLatin1All , IsHexDigitAll , IsOctDigitAll , IsDigitAll , IsPunctuationAll , IsSeparatorAll , IsSpaceAll)) "abc134"
+-- PresentT (False,True,True,False,False,False,False,False)
+--
+-- >>> pl @(SplitAts [1,2,10] Id >> Para '[IsLowerAll, IsDigitAll, IsUpperAll]) "abdefghi"
+-- Present [True,False,False] ((>>) [True,False,False] | {Para(0) [True,False,False] | ["a","bd","efghi"]})
+-- PresentT [True,False,False]
+--
+-- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll]) "a98efghi"
+-- False ((>>) False | {Bool(2) [] (IsUpperAll | "efghi")})
+-- FalseT
+--
+-- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll || IsLowerAll]) "a98efghi"
+-- True ((>>) True | {Bools})
+-- TrueT
+--
+-- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll || IsLowerAll]) "a98efgHi"
+-- False ((>>) False | {Bool(2) [] (False || False | (IsUpperAll | "efgHi") || (IsLowerAll | "efgHi"))})
+-- FalseT
+--
+data IsCharSetAll (cs :: CharSet)
+
+instance (GetCharSet cs
+        , Show a
+        , DTL.IsText a
+        ) => P (IsCharSetAll cs) a where
+  type PP (IsCharSetAll cs) a = Bool
+  eval _ opts as =
+    let b = allOf DTL.text f as
+        msg0 = "Is" ++ drop 1 (show cs) ++ "All"
+        (cs,f) = getCharSet @cs
+    in pure $ mkNodeB opts b (msg0 <> showVerbose opts " | " as) []
+
+data CharSet = CLower
+             | CUpper
+             | CNumber
+             | CSpace
+             | CPunctuation
+             | CControl
+             | CHexDigit
+             | COctDigit
+             | CSeparator
+             | CLatin1
+             deriving Show
+
+class GetCharSet (cs :: CharSet) where
+  getCharSet :: (CharSet, Char -> Bool)
+instance GetCharSet 'CLower where
+  getCharSet = (CLower, isLower)
+instance GetCharSet 'CUpper where
+  getCharSet = (CUpper, isUpper)
+instance GetCharSet 'CNumber where
+  getCharSet = (CNumber, isNumber)
+instance GetCharSet 'CSpace where
+  getCharSet = (CSpace, isSpace)
+instance GetCharSet 'CPunctuation where
+  getCharSet = (CPunctuation, isPunctuation)
+instance GetCharSet 'CControl where
+  getCharSet = (CControl, isControl)
+instance GetCharSet 'CHexDigit where
+  getCharSet = (CHexDigit, isHexDigit)
+instance GetCharSet 'COctDigit where
+  getCharSet = (COctDigit, isOctDigit)
+instance GetCharSet 'CSeparator where
+  getCharSet = (CSeparator, isSeparator)
+instance GetCharSet 'CLatin1 where
+  getCharSet = (CLatin1, isLatin1)
+
+-- | predicate for determining if a string is all lowercase
+--
+-- >>> pz @IsLowerAll "abc"
+-- TrueT
+--
+-- >>> pz @IsLowerAll "abcX"
+-- FalseT
+--
+-- >>> pz @IsLowerAll (T.pack "abcX")
+-- FalseT
+--
+-- >>> pz @IsLowerAll "abcdef213"
+-- FalseT
+--
+-- >>> pz @IsLowerAll ""
+-- TrueT
+--
+data IsLowerAll
+type IsLowerAllT = IsCharSetAll 'CLower
+
+instance P IsLowerAllT x => P IsLowerAll x where
+  type PP IsLowerAll x = PP IsLowerAllT x
+  eval _ = evalBool (Proxy @IsLowerAllT)
+
+data IsUpperAll
+type IsUpperAllT = IsCharSetAll 'CUpper
+
+instance P IsUpperAllT x => P IsUpperAll x where
+  type PP IsUpperAll x = PP IsUpperAllT x
+  eval _ = evalBool (Proxy @IsUpperAllT)
+
+-- | predicate for determining if the string is all digits
+--
+-- >>> pz @IsDigitAll "213G"
+-- FalseT
+--
+-- >>> pz @IsDigitAll "929"
+-- TrueT
+--
+data IsDigitAll
+type IsDigitAllT = IsCharSetAll 'CNumber
+instance P IsDigitAllT x => P IsDigitAll x where
+  type PP IsDigitAll x = Bool
+  eval _ = evalBool (Proxy @IsDigitAllT)
+
+-- | predicate for determining if the string is all spaces
+--
+-- >>> pz @IsSpaceAll "213G"
+-- FalseT
+--
+-- >>> pz @IsSpaceAll "    "
+-- TrueT
+--
+-- >>> pz @IsSpaceAll ""
+-- TrueT
+--
+data IsSpaceAll
+type IsSpaceAllT = IsCharSetAll 'CSpace
+instance P IsSpaceAllT x => P IsSpaceAll x where
+  type PP IsSpaceAll x = Bool
+  eval _ = evalBool (Proxy @IsSpaceAllT)
+
+data IsPunctuationAll
+type IsPunctuationAllT = IsCharSetAll 'CPunctuation
+instance P IsPunctuationAllT x => P IsPunctuationAll x where
+  type PP IsPunctuationAll x = Bool
+  eval _ = evalBool (Proxy @IsPunctuationAllT)
+
+data IsControlAll
+type IsControlAllT = IsCharSetAll 'CControl
+instance P IsControlAllT x => P IsControlAll x where
+  type PP IsControlAll x = Bool
+  eval _ = evalBool (Proxy @IsControlAllT)
+
+-- | predicate for determining if the string is all hex digits
+--
+-- >>> pz @IsHexDigitAll "01efA"
+-- TrueT
+--
+-- >>> pz @IsHexDigitAll "01egfA"
+-- FalseT
+--
+data IsHexDigitAll
+type IsHexDigitAllT = IsCharSetAll 'CHexDigit
+instance P IsHexDigitAllT x => P IsHexDigitAll x where
+  type PP IsHexDigitAll x = Bool
+  eval _ = evalBool (Proxy @IsHexDigitAllT)
+
+data IsOctDigitAll
+type IsOctDigitAllT = IsCharSetAll 'COctDigit
+instance P IsOctDigitAllT x => P IsOctDigitAll x where
+  type PP IsOctDigitAll x = Bool
+  eval _ = evalBool (Proxy @IsOctDigitAllT)
+
+data IsSeparatorAll
+type IsSeparatorAllT = IsCharSetAll 'CSeparator
+instance P IsSeparatorAllT x => P IsSeparatorAll x where
+  type PP IsSeparatorAll x = Bool
+  eval _ = evalBool (Proxy @IsSeparatorAllT)
+
+data IsLatin1All
+type IsLatin1AllT = IsCharSetAll 'CLatin1
+instance P IsLatin1AllT x => P IsLatin1All x where
+  type PP IsLatin1All x = Bool
+  eval _ = evalBool (Proxy @IsLatin1AllT)
+
+
+-- | converts a string 'Data.Text.Lens.IsText' value to lower case
+--
+-- >>> pz @ToLower "HeLlO wOrld!"
+-- PresentT "hello world!"
+--
+data ToLower
+
+instance ( Show a
+         , DTL.IsText a
+         ) => P ToLower a where
+  type PP ToLower a = a
+  eval _ opts as =
+    let msg0 = "ToLower"
+        xs = as & DTL.text %~ toLower
+    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
+
+-- | converts a string 'Data.Text.Lens.IsText' value to upper case
+--
+-- >>> pz @ToUpper "HeLlO wOrld!"
+-- PresentT "HELLO WORLD!"
+--
+data ToUpper
+
+instance ( Show a
+         , DTL.IsText a
+         ) => P ToUpper a where
+  type PP ToUpper a = a
+  eval _ opts as =
+    let msg0 = "ToUpper"
+        xs = as & DTL.text %~ toUpper
+    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
+
+
+-- | converts a string 'Data.Text.Lens.IsText' value to title case
+--
+-- >>> pz @ToTitle "HeLlO wOrld!"
+-- PresentT "Hello world!"
+--
+-- >>> data Color = Red | White | Blue | Green | Black deriving (Show,Eq,Enum,Bounded,Read)
+-- >>> pz @(ToTitle >> ReadP Color Id) "red"
+-- PresentT Red
+--
+data ToTitle
+
+instance ( Show a
+         , DTL.IsText a
+         ) => P ToTitle a where
+  type PP ToTitle a = a
+  eval _ opts as =
+    let msg0 = "ToTitle"
+        xs = toTitleAll (as ^. DTL.unpacked) ^. DTL.packed
+    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
+
+
+toTitleAll :: String -> String
+toTitleAll (x:xs) = toUpper x : map toLower xs
+toTitleAll [] = []
+
+ src/Predicate/Data/Condition.hs view
@@ -0,0 +1,921 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted conditional functions
+-}
+module Predicate.Data.Condition (
+  -- ** conditional expressions
+    If
+  , Case
+  , Case'
+  , Case''
+  , Guards
+  , GuardsQuick
+  , Guard
+  , ExitWhen
+  , GuardSimple
+  , GuardsN
+  , GuardsDetail
+
+  , Bools
+  , BoolsQuick
+  , BoolsN
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.ReadShow (PrintT)
+import GHC.TypeLits (Nat,KnownNat,ErrorMessage((:<>:)))
+import qualified GHC.TypeLits as GL
+import Control.Lens hiding (iall)
+import Data.Proxy
+import Data.Kind (Type)
+import Data.Void
+import qualified Data.Type.Equality as DE
+
+-- $setup
+-- >>> import Predicate.Prelude
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XAllowAmbiguousTypes
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> :set -XFlexibleContexts
+-- >>> import qualified Data.Text as T
+
+
+-- | similar to an if statement: if \'p\' then run \'q\' else run \'r\'
+--
+-- >>> pz @(If (Gt 4) "greater than 4" "less than or equal to 4") 10
+-- PresentT "greater than 4"
+--
+-- >>> pz @(If (Gt 4) "greater than 4" "less than or equal to 4") 0
+-- PresentT "less than or equal to 4"
+--
+-- >>> pz @(If (Snd Id == "a") '("xxx",Fst Id + 13) (If (Snd Id == "b") '("yyy",Fst Id + 7) (Failt _ "oops"))) (99,"b")
+-- PresentT ("yyy",106)
+--
+-- >>> pl @(If (Len > 2) (Map (Succ Id) Id) (FailS "someval")) [12,15,16]
+-- Present [13,16,17] (If (true cond))
+-- PresentT [13,16,17]
+--
+-- >>> pl @(Map (If (Lt 3) 'True (Failt _ "err")) Id) [1..10]
+-- Error err(8) (Map(i=2, a=3) excnt=8)
+-- FailT "err(8)"
+--
+-- >>> pl @(Map (If (Lt 3) 'True (Failt _ "someval")) Id) [1..10]
+-- Error someval(8) (Map(i=2, a=3) excnt=8)
+-- FailT "someval(8)"
+--
+-- >>> pl @(Map (If (Lt 3) 'True 'False) Id) [1..5]
+-- Present [True,True,False,False,False] (Map [True,True,False,False,False] | [1,2,3,4,5])
+-- PresentT [True,True,False,False,False]
+--
+-- >>> pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) ()) 45
+-- Error failing with 45 (If [True])
+-- FailT "failing with 45"
+--
+-- >>> pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (Id * 7)) 3
+-- Present 21 (If (false cond) 21)
+-- PresentT 21
+--
+-- >>> pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (Id * 7 >> ShowP Id >> Ones Id)) 3
+-- Present ["2","1"] (If (false cond) ["2","1"])
+-- PresentT ["2","1"]
+--
+-- >>> pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (ShowP (Id * 7) >> Ones Id)) 19
+-- Error failing with 19 (If [True])
+-- FailT "failing with 19"
+--
+data If p q r
+
+instance (Show (PP r a)
+        , P p a
+        , PP p a ~ Bool
+        , P q a
+        , P r a
+        , PP q a ~ PP r a
+        ) => P (If p q r) a where
+  type PP (If p q r) a = PP q a
+  eval _ opts a = do
+    let msg0 = "If"
+    pp <- evalBool (Proxy @p) opts a
+    case getValueLR opts (msg0 <> " condition failed") pp [] of
+      Left e -> pure e
+      Right b -> do
+        qqrr <- if b
+              then eval (Proxy @q) opts a
+              else eval (Proxy @r) opts a
+        pure $ case getValueLR opts (msg0 <> " [" <> show b <> "]") qqrr [hh pp, hh qqrr] of
+          Left e -> e
+          Right ret -> mkNode opts (_tBool qqrr) (msg0 <> " " <> if b then "(true cond)" else "(false cond) " <> showL opts ret) [hh pp, hh qqrr]
+
+type family GuardsT (ps :: [k]) where
+  GuardsT '[] = '[]
+  GuardsT (p ': ps) = Guard "fromGuardsT" p ': GuardsT ps
+
+--type Guards' (ps :: [k]) = Para (GuardsT ps)
+
+--type ToGuards (prt :: k) (os :: [k1]) = Proxy (Guards (ToGuardsT prt os))
+
+type family ToGuardsT (prt :: k) (os :: [k1]) :: [(k,k1)] where
+  ToGuardsT prt '[] = GL.TypeError ('GL.Text "ToGuardsT cannot be empty")
+  ToGuardsT prt '[p] = '(prt,p) : '[]
+  ToGuardsT prt (p ': ps) = '(prt,p) ': ToGuardsT prt ps
+
+-- | tries each predicate ps and on the first match runs the corresponding qs but if there is no match on ps then runs the fail case e
+--
+-- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 50
+-- PresentT "50 is same50"
+--
+-- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 9
+-- PresentT "9 is lt10"
+--
+-- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 3
+-- PresentT "3 is lt4"
+--
+-- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 99
+-- FailT "asdf"
+--
+-- >>> pz @(Case (FailS "asdf" >> Snd Id >> Unproxy) '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 99
+-- FailT "asdf"
+--
+-- >>> pz @(Case (Failt _ "x") '[Same "a",Same "b"] '["hey","there"] Id) "b"
+-- PresentT "there"
+--
+-- >>> pz @(Case (Failt _ "x") '[Id == "a",Id == "b"] '["hey","there"] Id) "a"
+-- PresentT "hey"
+--
+-- >>> pz @(Case (Failt _ "x") '[Same "a",Same "b"] '["hey","there"] Id) "c"
+-- FailT "x"
+--
+data CaseImpl (n :: Nat) (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
+-- ps = conditions
+-- qs = what to do [one to one with ps]
+-- r = the value
+-- e = otherwise  -- leave til later
+
+-- | tries to match the value \'r\' with a condition in \'ps\' and if there is a match calls the associated \'qs\' entry else run \'e\'
+--
+-- >>> pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 15
+-- Present "gt3" (Case(0 of 3) "gt3" | 15)
+-- PresentT "gt3"
+--
+-- >>> pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 1
+-- Present "lt2" (Case(0) "lt2" | 1)
+-- PresentT "lt2"
+--
+-- >>> pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 3
+-- Present "eq3" (Case(0) "eq3" | 3)
+-- PresentT "eq3"
+--
+-- >>> pl @(Case (Snd Id >> Failp "no match") '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Error no match (Case(0) failed rhs)
+-- FailT "no match"
+--
+-- >>> pl @(Case (Fail (Snd Id >> Unproxy) (PrintF "no match for %03d" (Fst Id))) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Error no match for 015 (Case(0) failed rhs)
+-- FailT "no match for 015"
+--
+-- >>> pl @(Case "other" '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Present "other" (Case(0) "other" | 15)
+-- PresentT "other"
+--
+-- >>> pl @(Case (ShowP (Fst Id) >> Id <> Id <> Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Present "151515" (Case(0) "151515" | 15)
+-- PresentT "151515"
+--
+data Case (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
+
+-- | like 'Case' but uses a generic error message (skips the \'e\' parameter)
+--
+-- >>> pl @(Case' '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Error Case:no match (Case(0) failed rhs)
+-- FailT "Case:no match"
+--
+data Case' (ps :: [k]) (qs :: [k1]) (r :: k2)
+
+-- | like 'Case' but allows you to use the value in the error message
+--
+-- >>> pl @(Case'' (PrintF "no match for %03d" Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Error no match for 015 (Case(0) failed rhs)
+-- FailT "no match for 015"
+--
+-- >>> pl @(Case'' (PrintF "no match for %03d" Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
+-- Error no match for 015 (Case(0) failed rhs)
+-- FailT "no match for 015"
+--
+-- >>> pl @(Case'' (PrintF "no match for %04d" Id) '[Between 0 5 Id, Same 6, Between 7 10 Id] '[ 'LT, 'EQ, 'GT] Id) (-12)
+-- Error no match for -012 (Case(0) failed rhs)
+-- FailT "no match for -012"
+--
+data Case'' s (ps :: [k]) (qs :: [k1]) (r :: k2)
+
+type CaseT' (ps :: [k]) (qs :: [k1]) (r :: k2) = Case (Snd Id >> Failp "Case:no match") ps qs r
+type CaseT'' s (ps :: [k]) (qs :: [k1]) (r :: k2) = Case (FailCaseT s) ps qs r -- eg s= PrintF "%s" (ShowP Id)
+
+instance P (CaseT'' s ps qs r) x => P (Case'' s ps qs r) x where
+  type PP (Case'' s ps qs r) x = PP (CaseT'' s ps qs r) x
+  eval _ = eval (Proxy @(CaseT'' s ps qs r))
+
+instance P (CaseT' ps qs r) x => P (Case' ps qs r) x where
+  type PP (Case' ps qs r) x = PP (CaseT' ps qs r) x
+  eval _ = eval (Proxy @(CaseT' ps qs r))
+
+type FailCaseT p = Fail (Snd Id >> Unproxy) (Fst Id >> p)
+
+type CaseImplT e ps qs r = CaseImpl (LenT ps) e ps qs r
+
+-- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out
+instance (FailUnlessT (LenT ps DE.== LenT qs)
+                  ('GL.Text "lengths are not the same "
+                   ':<>: 'GL.ShowType (LenT ps)
+                   ':<>: 'GL.Text " vs "
+                   ':<>: 'GL.ShowType (LenT qs))
+        , P (CaseImplT e ps qs r) x
+        ) => P (Case e ps qs r) x where
+  type PP (Case e ps qs r) x = PP (CaseImplT e ps qs r) x
+  eval _ = eval (Proxy @(CaseImplT e ps qs r))
+
+-- only allow non empty lists!
+instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: lhs requires at least one value in the list"))
+   => P (CaseImpl n e ('[] :: [k]) (q ': qs) r) x where
+  type PP (CaseImpl n e ('[] :: [k]) (q ': qs) r) x = Void
+  eval _ _ _ = errorInProgram "CaseImpl lhs empty"
+
+instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: rhs requires at least one value in the list"))
+   => P (CaseImpl n e (p ': ps) ('[] :: [k1]) r) x where
+  type PP (CaseImpl n e (p ': ps) ('[] :: [k1]) r) x = Void
+  eval _ _ _ = errorInProgram "CaseImpl rhs empty"
+
+instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: lists are both empty"))
+   => P (CaseImpl n e ('[] :: [k]) ('[] :: [k1]) r) x where
+  type PP (CaseImpl n e ('[] :: [k]) ('[] :: [k1]) r) x = Void
+  eval _ _ _ = errorInProgram "CaseImpl both lists empty"
+
+instance (P r x
+        , P q (PP r x)
+        , Show (PP q (PP r x))
+        , P p (PP r x)
+        , PP p (PP r x) ~ Bool
+        , KnownNat n
+        , Show (PP r x)
+        , P e (PP r x, Proxy (PP q (PP r x)))
+        , PP e (PP r x, Proxy (PP q (PP r x))) ~ PP q (PP r x)
+        ) => P (CaseImpl n e '[p] '[q] r) x where
+  type PP (CaseImpl n e '[p] '[q] r) x = PP q (PP r x)
+  eval _ opts z = do
+    let msgbase0 = "Case(" <> show n <> ")"
+        n :: Int = nat @n
+    rr <- eval (Proxy @r) opts z
+    case getValueLR opts msgbase0 rr [] of
+      Left e -> pure e
+      Right a -> do
+        pp <- evalBool (Proxy @p) opts a
+        case getValueLR opts msgbase0 pp [hh rr] of
+          Left e -> pure e
+          Right True -> do
+            qq <- eval (Proxy @q) opts a
+            pure $ case getValueLR opts msgbase0 qq [hh rr, hh pp] of
+              Left e -> e
+              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) (hh rr : hh pp : [hh qq | isVerbose opts])
+          Right False -> do
+            ee <- eval (Proxy @e) opts (a, Proxy @(PP q (PP r x)))
+            pure $ case getValueLR opts (msgbase0 <> "  otherwise failed") ee [hh rr, hh pp] of
+              Left e -> e
+              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) [hh rr, hh pp, hh ee]
+
+instance (KnownNat n
+        , GetLen ps
+        , P r x
+        , P p (PP r x)
+        , P q (PP r x)
+        , PP p (PP r x) ~ Bool
+        , Show (PP q (PP r x))
+        , Show (PP r x)
+        , P (CaseImpl n e (p1 ': ps) (q1 ': qs) r) x
+        , PP (CaseImpl n e (p1 ': ps) (q1 ': qs) r) x ~ PP q (PP r x)
+        )
+     => P (CaseImpl n e (p ': p1 ': ps) (q ': q1 ': qs) r) x where
+  type PP (CaseImpl n e (p ': p1 ': ps) (q ': q1 ': qs) r) x = PP q (PP r x)
+  eval _ opts z = do
+    let cpos = n-pos-1
+        msgbase0 = msgbase2 <> "(" <> showIndex cpos <> " of " <> show n <> ")"
+        msgbase1 = msgbase2 <> "(" <> showIndex cpos <> ")"
+        msgbase2 = "Case"
+        n = nat @n
+        pos = 1 + getLen @ps -- cos p1!
+    rr <- eval (Proxy @r) opts z
+    case getValueLR opts msgbase0 rr [] of
+      Left e -> pure e
+      Right a -> do
+        pp <- evalBool (Proxy @p) opts a
+        case getValueLR opts msgbase0 pp [hh rr] of
+          Left e -> pure e
+          Right True -> do
+            qq <- eval (Proxy @q) opts a
+            pure $ case getValueLR opts msgbase0 qq [hh pp, hh rr] of
+              Left e -> e
+              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) (hh rr : hh pp : [hh qq | isVerbose opts])
+          Right False -> do
+            ww <- eval (Proxy @(CaseImpl n e (p1 ': ps) (q1 ': qs) r)) opts z
+            pure $ case getValueLR opts (msgbase1 <> " failed rhs") ww [hh rr, hh pp] of
+              Left e -> e
+              Right b -> mkNode opts (PresentT b) (show01 opts msgbase1 b a) [hh rr, hh pp, hh ww]
+
+
+data GuardsImpl (n :: Nat) (os :: [(k,k1)])
+
+-- isbn 10 tests (dont need first guard as Zip enforces same length: handles case insensitive \'x\' as check digit)
+
+
+-- | Guards contain a type level list of tuples the action to run on failure of the predicate and the predicate itself
+--   Each tuple validating against the corresponding value in a value list
+--
+-- \'prt\' receives (Int,a) as input which is the position and value if there is a failure
+--
+-- >>> pz @(Guards '[ '("arg1 failed",Gt 4), '("arg2 failed", Same 4)]) [17,4]
+-- PresentT [17,4]
+--
+-- >>> pz @(Guards '[ '("arg1 failed",Gt 4), '("arg2 failed", Same 5)]) [17,4]
+-- FailT "arg2 failed"
+--
+-- >>> pz @(Guards '[ '("arg1 failed",Gt 99), '("arg2 failed", Same 4)]) [17,4]
+-- FailT "arg1 failed"
+--
+-- >>> pz @(Guards '[ '(PrintT "arg %d failed with value %d" Id,Gt 4), '(PrintT "%d %d" Id, Same 4)]) [17,3]
+-- FailT "1 3"
+--
+-- >>> pz @(Msg "isbn10" (Resplit "-" Id) >> Concat Id >> 'Just Unsnoc >> Map (ReadP Int (Singleton Id)) Id *** If (Singleton Id ==~ "X") 10 (ReadP Int (Singleton Id)) >> Zip (1...10 >> Reverse) (Fst Id +: Snd Id) >> Map (Fst Id * Snd Id) Id >> Sum >> Guard ("mod 0 oops") (Id `Mod` 11 == 0)) "0-306-40614-X"
+-- FailT "mod 0 oops"
+--
+-- >>> pz @(Resplit "-" Id >> Concat Id >> 'Just Unsnoc >> Map (ReadP Int (Singleton Id)) Id *** If (Singleton Id ==~ "X") 10 (ReadP Int (Singleton Id)) >> Zip (1...10 >> Reverse) (Fst Id +: Snd Id) >> Map (Fst Id * Snd Id) Id >> Sum >> Guard ("mod 0 oops") (Id `Mod` 11 == 0)) "0-306-40611-X"
+-- PresentT 132
+--
+-- >>> pz @(Msg "isbn13" (Resplit "-" Id) >> Concat Id >> Map (ReadP Int (Singleton Id)) Id >> Zip (Cycle 13 [1,3] >> Reverse) Id >> Map (Fst Id * Snd Id) Id >> Sum >> '(Id,Id `Mod` 10) >> Guard (PrintT "sum=%d mod 10=%d" Id) (Snd Id == 0)) "978-0-306-40615-7"
+-- PresentT (100,0)
+--
+-- >>> pz @(Resplit "-" Id >> Concat Id >> Map (ReadP Int (Singleton Id)) Id >> Zip (Cycle 13 [1,3] >> Reverse) Id >> Map (Fst Id * Snd Id) Id >> Sum >> '(Id,Id `Mod` 10) >> Guard (PrintT "sum=%d mod 10=%d" Id) (Snd Id == 0)) "978-0-306-40615-8"
+-- FailT "sum=101 mod 10=1"
+--
+-- >>> pz @(Do '[Resplit "-" Id, Concat Id, Zip (Cycle 13 [1,3]) (Map (ReadP Int (Singleton Id)) Id), Map (Fst Id * Snd Id) Id, Sum, Guard (PrintF "%d is not evenly divisible by 10" Id) (Id `Mod` 10 == 0)]) "978-0-7167-0344-9"
+-- FailT "109 is not evenly divisible by 10"
+--
+-- >>> pz @(Do '[Resplit "-" Id, Concat Id, Zip (Cycle 13 [1,3]) (Map (ReadP Int (Singleton Id)) Id), Map (Fst Id * Snd Id) Id, Sum, Guard (PrintF "%d is not evenly divisible by 10" Id) (Id `Mod` 10 == 0)]) "978-0-7167-0344-0"
+-- PresentT 100
+--
+data Guards (ps :: [(k,k1)])
+
+instance ( [a] ~ x
+         , GetLen ps
+         , P (GuardsImpl (LenT ps) ps) x
+         ) => P (Guards ps) x where
+  type PP (Guards ps) x = PP (GuardsImpl (LenT ps) ps) x
+  eval _ opts as = do
+    let msg0 = "Guards"
+        n = getLen @ps
+    if n /= length as then
+       let msg1 = msg0 <> badLength as n
+       in pure $ mkNode opts (FailT msg1) "" []
+    else eval (Proxy @(GuardsImpl (LenT ps) ps)) opts as
+
+instance ( [a] ~ x
+         , Show a
+         ) => P (GuardsImpl n ('[] :: [(k,k1)])) x where
+  type PP (GuardsImpl n ('[] :: [(k,k1)])) x = x
+  eval _ opts as =
+    let msg0 = "Guards"
+    in if not (null as) then errorInProgram $ "GuardsImpl base case has extra data " ++ show as
+       else pure $ mkNode opts (PresentT as) (msg0 <> " no data") []
+
+instance (PP prt (Int, a) ~ String
+        , P prt (Int, a)
+        , KnownNat n
+        , GetLen ps
+        , P p a
+        , PP p a ~ Bool
+        , P (GuardsImpl n ps) [a]
+        , PP (GuardsImpl n ps) [a] ~ [a]
+        , Show a
+        , [a] ~ x
+        ) => P (GuardsImpl n ('(prt,p) ': ps)) x where
+  type PP (GuardsImpl n ('(prt,p) ': ps)) x = x
+  eval _ opts as' = do
+     let cpos = n-pos-1
+         msgbase1 = "Guard(" <> show cpos <> ")"
+         msgbase2 = "Guards"
+         n :: Int
+         n = nat @n
+         pos = getLen @ps
+     case as' of
+         a:as -> do
+            pp <- evalBoolHide @p opts a
+            case getValueLR opts (msgbase1 <> " p failed") pp [] of
+                 Left e -> pure e
+                 Right False -> do
+                   qq <- eval (Proxy @prt) opts (cpos,a) -- only run prt when predicate is False
+                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
+                      Left e -> e
+                      Right msgx -> mkNode opts (FailT msgx) (msgbase1 <> " failed [" <> msgx <> "] " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
+                 Right True ->
+                   if pos == 0 then -- we are at the bottom of the tree
+                      pure $ mkNode opts (PresentT [a]) msgbase2 [hh pp]
+                   else do
+                     ss <- eval (Proxy @(GuardsImpl n ps)) opts as
+                     pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
+                       Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
+                       Right zs -> (ss & tForest %~ \x -> fromTT pp : x) & tBool .~ PresentT (a:zs)
+         _ -> errorInProgram "GuardsImpl n+1 case has no data"
+
+-- | GuardsQuick contain a type level list of conditions and one of matching values: on no match will fail using the first parameter
+--
+-- >>> pz @(GuardsQuick (PrintT "arg %d failed with value %d" Id) '[Gt 4, Ge 3, Same 4]) [17,3,5]
+-- FailT "arg 2 failed with value 5"
+--
+-- >>> pz @(GuardsQuick (PrintT "arg %d failed with value %d" Id) '[Gt 4, Ge 3, Same 4]) [17,3,5,99]
+-- FailT "Guards:invalid length(4) expected 3"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 0 11 Id, Between 1 4 Id,Between 3 5 Id]) [10::Int,2,5]
+-- Present [10,2,5] (Guards)
+-- PresentT [10,2,5]
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11,1999::Int]
+-- Present [31,11,1999] (Guards)
+-- PresentT [31,11,1999]
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11::Int]
+-- Error Guards:invalid length(2) expected 3
+-- FailT "Guards:invalid length(2) expected 3"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,13,1999::Int]
+-- Error guard(1) 13 is out of range (Guard(0) ok | rhs failed)
+-- FailT "guard(1) 13 is out of range"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [0,44,1999::Int]
+-- Error guard(0) 0 is out of range (Guard(0) failed [guard(0) 0 is out of range] 0)
+-- FailT "guard(0) 0 is out of range"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11,2000,1,2::Int]
+-- Error Guards:invalid length(5) expected 3
+-- FailT "Guards:invalid length(5) expected 3"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[W 'True, Ge 12, W 'False, Lt 2]) [1,2,-99,-999]
+-- Error guard(1) err 002 (Guard(0) ok | rhs failed)
+-- FailT "guard(1) err 002"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[W 'True, Ge 12, W 'False, Lt 2]) [1,2,-99]
+-- Error Guards:invalid length(3) expected 4
+-- FailT "Guards:invalid length(3) expected 4"
+--
+-- >>> pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[W 'True, Ge 12, W 'True, Lt 2]) [1,22,-99,-999,1,1,2]
+-- Error Guards:invalid length(7) expected 4
+-- FailT "Guards:invalid length(7) expected 4"
+--
+data GuardsQuick (prt :: k) (ps :: [k1])
+type GuardsQuickT (prt :: k) (ps :: [k1]) = Guards (ToGuardsT prt ps)
+
+instance P (GuardsQuickT prt ps) x => P (GuardsQuick prt ps) x where
+  type PP (GuardsQuick prt ps) x = PP (GuardsQuickT prt ps) x
+  eval _ = eval (Proxy @(GuardsQuickT prt ps))
+
+-- prefer 'Bools' as 'BoolsQuick' doesnt give much added value: passes in the index and the value to prt but you already have the index in the message
+-- pulls the top message from the tree if a predicate is false
+
+-- | boolean guard which checks a given a list of predicates against the list of values
+--
+-- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ]) [12,93,14]
+-- False (Bool(1) [mm] (93 <= 59))
+-- FalseT
+--
+-- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ]) [12,13,94]
+-- False (Bool(2) [<<<2 94>>>] (94 <= 59))
+-- FalseT
+--
+-- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ]) [12,13,14]
+-- True (Bools)
+-- TrueT
+--
+-- >>> pl @(BoolsQuick "abc" '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,14]
+-- True (Bools)
+-- TrueT
+--
+-- >>> pl @(BoolsQuick (PrintT "id=%d val=%d" Id) '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,14]
+-- True (Bools)
+-- TrueT
+--
+-- >>> pl @(BoolsQuick (PrintT "id=%d val=%d" Id) '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,99]
+-- False (Bool(2) [id=2 val=99] (99 <= 59))
+-- FalseT
+--
+-- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id)]) [12,13,14]
+-- True (Bools)
+-- TrueT
+--
+-- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id)]) [12,60,14]
+-- False (Bool(1) [minutes] (60 <= 59))
+-- FalseT
+--
+-- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id)]) [12,60,14,20]
+-- False (Bools:invalid length(4) expected 3)
+-- FalseT
+--
+data Bools (ps :: [(k,k1)])
+
+instance ([a] ~ x
+        , GetLen ps
+        , P (BoolsImpl (LenT ps) ps) x
+        , PP (BoolsImpl (LenT ps) ps) x ~ Bool
+        ) => P (Bools ps) x where
+  type PP (Bools ps) x = Bool
+  eval _ opts as = do
+    let msg0 = "Bools"
+        msg1 = "Bool("++show n++")"
+        n = getLen @ps
+    case chkSize opts msg1 as [] of
+      Left e -> pure e
+      Right () ->
+        if n /= length as then
+           let msg2 = msg0 <> badLength as n
+           in pure $ mkNodeB opts False msg2 [] -- was FailT but now just FalseT
+        else evalBool (Proxy @(BoolsImpl (LenT ps) ps)) opts as
+
+data BoolsImpl (n :: Nat) (os :: [(k,k1)])
+
+instance (KnownNat n
+        , Show a
+        , [a] ~ x
+        ) => P (BoolsImpl n ('[] :: [(k,k1)])) x where
+  type PP (BoolsImpl n ('[] :: [(k,k1)])) x = Bool
+  eval _ opts as =
+    let msg0 = "Bool(" <> show n <> ")"
+        n :: Int = nat @n
+    in if not (null as) then errorInProgram $ "BoolsImpl base case has extra data " ++ show as
+       else pure $ mkNodeB opts True (msg0 <> " empty") []
+
+instance (PP prt (Int, a) ~ String
+        , P prt (Int, a)
+        , KnownNat n
+        , GetLen ps
+        , P p a
+        , PP p a ~ Bool
+        , P (BoolsImpl n ps) x
+        , PP (BoolsImpl n ps) [a] ~ Bool
+--        , Show a
+        , [a] ~ x
+        ) => P (BoolsImpl n ('(prt,p) ': ps)) x where
+  type PP (BoolsImpl n ('(prt,p) ': ps)) x = Bool
+  eval _ opts as' = do
+     let cpos = n-pos-1
+         msgbase1 = "Bool(" <> showIndex cpos <> ")"
+         msgbase2 = "Bools"
+         n :: Int = nat @n
+         pos = getLen @ps
+     case as' of
+         a:as -> do
+            pp <- evalBoolHide @p opts a
+            case getValueLR opts (msgbase1 <> " p failed") pp [] of
+                 Left e -> pure e
+                 Right False -> do
+                   qq <- eval (Proxy @prt) opts (cpos,a) -- only run prt when predicate is False
+                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
+                      Left e -> e
+                      Right msgx -> mkNodeB opts False (msgbase1 <> " [" <> msgx <> "] " <> topMessage pp) (hh pp : [hh qq | isVerbose opts])
+                 Right True ->
+                   if pos == 0 then -- we are at the bottom of the tree
+                      pure $ mkNodeB opts True msgbase2 [hh pp]
+                   else do
+                     ss <- evalBool (Proxy @(BoolsImpl n ps)) opts as
+                     pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
+                       Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
+                       Right _ ->  ss & tForest %~ \x -> fromTT pp : x
+         _ -> errorInProgram "BoolsImpl n+1 case has no data"
+
+data BoolsQuick (prt :: k) (ps :: [k1])
+type BoolsQuickT (prt :: k) (ps :: [k1]) = Bools (ToGuardsT prt ps)
+
+-- why do we need this? when BoolsN works without [use the x ~ [a] trick in BoolsN]
+instance (PP (Bools (ToGuardsT prt ps)) x ~ Bool
+        , P (BoolsQuickT prt ps) x
+          ) => P (BoolsQuick prt ps) x where
+  type PP (BoolsQuick prt ps) x = PP (BoolsQuickT prt ps) x
+  eval _ = evalBool (Proxy @(BoolsQuickT prt ps))
+
+-- | leverages 'RepeatT' for repeating predicates (passthrough method)
+--
+-- >>> pl @(BoolsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,256]
+-- False (Bool(3) [id=3 must be between 0 and 255, found 256] (256 <= 255))
+-- FalseT
+--
+-- >>> pl @(BoolsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,44]
+-- True (Bools)
+-- TrueT
+--
+data BoolsN prt (n :: Nat) (p :: k1)
+type BoolsNT prt (n :: Nat) (p :: k1) = Bools (ToGuardsT prt (RepeatT n p))
+
+instance ( x ~ [a]
+         , P (BoolsNT prt n p) x
+         ) => P (BoolsN prt n p) x where
+  type PP (BoolsN prt n p) x = PP (BoolsNT prt n p) x
+  eval _ = evalBool (Proxy @(BoolsNT prt n p))
+
+-- | if a predicate fails then then the corresponding symbol and value will be passed to the print function
+--
+-- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [13,59,61]
+-- FailT "seconds invalid: found 61"
+--
+-- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [27,59,12]
+-- FailT "hours invalid: found 27"
+--
+-- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [23,59,12]
+-- PresentT [23,59,12]
+--
+data GuardsDetailImpl (ps :: [(k,k1)])
+
+instance ([a] ~ x
+        , GetLen ps
+        , P (GuardsImplX (LenT ps) ps) x
+        ) => P (GuardsDetailImpl ps) x where
+  type PP (GuardsDetailImpl ps) x = PP (GuardsImplX (LenT ps) ps) x
+  eval _ opts as = do
+    let msg0 = "Guards"
+        n = getLen @ps
+    if n /= length as then
+       let msg1 = msg0 <> badLength as n
+       in pure $ mkNode opts (FailT msg1) "" []
+    else eval (Proxy @(GuardsImplX (LenT ps) ps)) opts as
+
+data GuardsImplX (n :: Nat) (os :: [(k,k1)])
+
+instance ( [a] ~ x
+         , Show a
+         ) => P (GuardsImplX n ('[] :: [(k,k1)])) x where
+  type PP (GuardsImplX n ('[] :: [(k,k1)])) x = x
+  eval _ opts as =
+    let msg0 = "Guards"
+        -- n :: Int = nat @n
+    in if not (null as) then errorInProgram $ "GuardsImplX base case has extra data " ++ show as
+       else pure $ mkNode opts (PresentT as) msg0 []
+
+instance (PP prt a ~ String
+        , P prt a
+        , KnownNat n
+        , GetLen ps
+        , P p a
+        , PP p a ~ Bool
+        , P (GuardsImplX n ps) [a]
+        , PP (GuardsImplX n ps) [a] ~ [a]
+        , Show a
+        , [a] ~ x
+        ) => P (GuardsImplX n ('(prt,p) ': ps)) x where
+  type PP (GuardsImplX n ('(prt,p) ': ps)) x = x
+  eval _ opts as' = do
+     let cpos = n-pos-1
+         msgbase1 = "Guard(" <> showIndex cpos <> ")"
+         msgbase2 = "Guards"
+         n :: Int = nat @n
+         pos = getLen @ps
+     case as' of
+         a:as -> do
+            pp <- evalBoolHide @p opts a
+            case getValueLR opts (msgbase1 <> " p failed") pp [] of
+                 Left e -> pure e
+                 Right False -> do
+                   qq <- eval (Proxy @prt) opts a -- only run prt when predicate is False
+                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
+                      Left e -> e
+                      Right msgx -> mkNode opts (FailT msgx) (msgbase1 <> " failed [" <> msgx <> "] " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
+                 Right True -> do
+                   ss <- eval (Proxy @(GuardsImplX n ps)) opts as
+                   pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
+                     Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
+                     Right zs -> mkNode opts (PresentT (a:zs)) (msgbase1 <> " " <> showL opts a) [hh pp, hh ss]
+         _ -> errorInProgram "GuardsImplX n+1 case has no data"
+
+data GuardsDetail prt (ps :: [(k0,k1)])
+type GuardsDetailT prt (ps :: [(k0,k1)]) = GuardsDetailImpl (ToGuardsDetailT prt ps)
+
+instance P (GuardsDetailT prt ps) x => P (GuardsDetail prt ps) x where
+  type PP (GuardsDetail prt ps) x = PP (GuardsDetailT prt ps) x
+  eval _ = eval (Proxy @(GuardsDetailT prt ps))
+
+type family ToGuardsDetailT (prt :: k1) (os :: [(k2,k3)]) :: [(Type,k3)] where
+  ToGuardsDetailT prt '[ '(s,p) ] = '(PrintT prt '(s,Id), p) : '[]
+  ToGuardsDetailT prt ( '(s,p) ': ps) = '(PrintT prt '(s,Id), p) ': ToGuardsDetailT prt ps
+  ToGuardsDetailT prt '[] = GL.TypeError ('GL.Text "ToGuardsDetailT cannot be empty")
+
+-- | leverages 'RepeatT' for repeating predicates (passthrough method)
+--
+-- >>> pz @(GuardsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,256]
+-- FailT "id=3 must be between 0 and 255, found 256"
+--
+-- >>> pz @(GuardsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,44]
+-- PresentT [121,33,7,44]
+--
+-- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3,4::Int]
+-- Present [1,2,3,4] (Guards)
+-- PresentT [1,2,3,4]
+--
+-- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3,4,5::Int]
+-- Error Guards:invalid length(5) expected 4
+-- FailT "Guards:invalid length(5) expected 4"
+--
+-- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3::Int]
+-- Error Guards:invalid length(3) expected 4
+-- FailT "Guards:invalid length(3) expected 4"
+--
+data GuardsN prt (n :: Nat) p
+type GuardsNT prt (n :: Nat) p = Guards (ToGuardsT prt (RepeatT n p))
+
+instance ( x ~ [a]
+         , P (GuardsNT prt n p) x
+         ) => P (GuardsN prt n p) x where
+  type PP (GuardsN prt n p) x = PP (GuardsNT prt n p) x
+  eval _ = eval (Proxy @(GuardsNT prt n p))
+
+-- | \'p\' is the predicate and on failure of the predicate runs \'prt\'
+--
+-- >>> pz @(Guard "expected > 3" (Gt 3)) 17
+-- PresentT 17
+--
+-- >>> pz @(Guard "expected > 3" (Gt 3)) 1
+-- FailT "expected > 3"
+--
+-- >>> pz @(Guard (PrintF "%d not > 3" Id) (Gt 3)) (-99)
+-- FailT "-99 not > 3"
+--
+-- >>> pl @(Map (Guard "someval" (Lt 3) >> 'True) Id) [1::Int ..10]
+-- Error someval(8) (Map(i=2, a=3) excnt=8)
+-- FailT "someval(8)"
+--
+-- >>> pl @(Guard "someval" (Len == 2) >> (ShowP Id &&& Id)) ([] :: [Int])
+-- Error someval ((>>) lhs failed)
+-- FailT "someval"
+--
+-- >>> pl @(Guard "someval" (Len == 2) >> (Id &&& ShowP Id)) [2,3]
+-- Present ([2,3],"[2,3]") ((>>) ([2,3],"[2,3]") | {W '([2,3],"[2,3]")})
+-- PresentT ([2,3],"[2,3]")
+--
+-- >>> pl @(Guard "someval" (Len == 2) >> (ShowP Id &&& Id)) [2,3,4]
+-- Error someval ((>>) lhs failed)
+-- FailT "someval"
+--
+-- >>> pl @(Map (Guard "someval" (Lt 3) >> 'True) Id) [1::Int ..10]
+-- Error someval(8) (Map(i=2, a=3) excnt=8)
+-- FailT "someval(8)"
+--
+-- >>> pl @(Guard "oops" (Len > 2) >> Map (Succ Id) Id) [12,15,16]
+-- Present [13,16,17] ((>>) [13,16,17] | {Map [13,16,17] | [12,15,16]})
+-- PresentT [13,16,17]
+--
+-- >>> pl @(Guard "err" (Len > 2) >> Map (Succ Id) Id) [12]
+-- Error err ((>>) lhs failed)
+-- FailT "err"
+--
+-- >>> pl @(Guard (PrintF "err found len=%d" Len) (Len > 5) >> Map (Succ Id) Id) [12,15,16]
+-- Error err found len=3 ((>>) lhs failed)
+-- FailT "err found len=3"
+--
+data Guard prt p
+
+
+instance (Show a
+        , P prt a
+        , PP prt a ~ String
+        , P p a
+        , PP p a ~ Bool
+        ) => P (Guard prt p) a where
+  type PP (Guard prt p) a = a
+  eval _ opts a = do
+    let msg0 = "Guard"
+    pp <- evalBool (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right False -> do
+        qq <- eval (Proxy @prt) opts a
+        pure $ case getValueLR opts (msg0 <> " Msg") qq [hh pp] of
+          Left e -> e
+          Right ee -> mkNode opts (FailT ee) (msg0 <> " | " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
+      Right True -> pure $ mkNode opts (PresentT a) (msg0 <> "(ok) | " <> showL opts a) [hh pp]  -- dont show the guard message if successful
+
+-- | uses 'Guard' but negates \'p\'
+--
+-- >>> pl @(HeadFail "failedn" Id &&& (Len == 1 >> ExitWhen "ExitWhen" Id) >> Fst Id) [3]
+-- Error ExitWhen ((>>) lhs failed)
+-- FailT "ExitWhen"
+--
+-- >>> pl @(Head Id &&& (Len == 1 >> Not Id >> ExitWhen "ExitWhen" Id) >> Fst Id) [3]
+-- Present 3 ((>>) 3 | {Fst 3 | (3,False)})
+-- PresentT 3
+--
+-- >>> pl @(Head Id &&& (Len == 1 >> ExitWhen "ExitWhen" (Not Id)) >> Fst Id) [3]
+-- Present 3 ((>>) 3 | {Fst 3 | (3,True)})
+-- PresentT 3
+--
+-- >>> pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id) [3,1]
+-- Error ExitWhen ((>>) lhs failed)
+-- FailT "ExitWhen"
+--
+-- >>> pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id) [3]
+-- Present 3 ((>>) 3 | {Head 3 | [3]})
+-- PresentT 3
+--
+-- >>> pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id >> Gt (20 -% 1)) [3]
+-- True ((>>) True | {3 % 1 > (-20) % 1})
+-- TrueT
+--
+-- >>> pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id >> Gt (20 -% 1)) [-23]
+-- False ((>>) False | {(-23) % 1 > (-20) % 1})
+-- FalseT
+--
+-- >>> pl @(Map (ExitWhen "ExitWhen" (Gt 10) >> Gt 2) Id) [1..5]
+-- Present [False,False,True,True,True] (Map [False,False,True,True,True] | [1,2,3,4,5])
+-- PresentT [False,False,True,True,True]
+--
+-- >>> pl @(ExitWhen "err" (Len > 2) >> Map (Succ Id) Id) [12,15,16]
+-- Error err ((>>) lhs failed)
+-- FailT "err"
+--
+-- >>> pl @(ExitWhen "err" (Len > 2) >> Map (Succ Id) Id) [12]
+-- Present [13] ((>>) [13] | {Map [13] | [12]})
+-- PresentT [13]
+--
+
+data ExitWhen prt p
+type ExitWhenT prt p = Guard prt (Not p)
+
+instance P (ExitWhenT prt p) x => P (ExitWhen prt p) x where
+  type PP (ExitWhen prt p) x = PP (ExitWhenT prt p) x
+  eval _ = eval (Proxy @(ExitWhenT prt p))
+
+-- | similar to 'Guard' but uses the root message of the False predicate case as the failure message
+--
+-- most uses of GuardSimple can be replaced by a boolean predicate unless you require a failure message instead of true/false
+--
+-- >>> pz @(GuardSimple (Luhn Id)) [1..4]
+-- FailT "(Luhn map=[4,6,2,2] sum=14 ret=4 | [1,2,3,4])"
+--
+-- >>> pl @(Luhn Id) [1..4]
+-- False (Luhn map=[4,6,2,2] sum=14 ret=4 | [1,2,3,4])
+-- FalseT
+--
+-- >>> pz @(GuardSimple (Luhn Id)) [1,2,3,0]
+-- PresentT [1,2,3,0]
+--
+-- >>> pz @(GuardSimple (Len > 30)) [1,2,3,0]
+-- FailT "(4 > 30)"
+--
+-- >>> pl @(Map (GuardSimple (Lt 3) >> 'True) Id) [1::Int .. 10]
+-- Error (3 < 3) | (4 < 3) | (5 < 3) | (6 < 3) | (7 < 3) | (8 < 3) | (9 < 3) | (10 < 3) (Map(i=2, a=3) excnt=8)
+-- FailT "(3 < 3) | (4 < 3) | (5 < 3) | (6 < 3) | (7 < 3) | (8 < 3) | (9 < 3) | (10 < 3)"
+--
+-- >>> pl @(Map (GuardSimple (Ge 1) >> 'True) Id) [1::Int .. 10]
+-- Present [True,True,True,True,True,True,True,True,True,True] (Map [True,True,True,True,True,True,True,True,True,True] | [1,2,3,4,5,6,7,8,9,10])
+-- PresentT [True,True,True,True,True,True,True,True,True,True]
+--
+-- >>> pl @(Map (GuardSimple (Lt 3) >> 'True) Id) [1::Int .. 10]
+-- Error (3 < 3) | (4 < 3) | (5 < 3) | (6 < 3) | (7 < 3) | (8 < 3) | (9 < 3) | (10 < 3) (Map(i=2, a=3) excnt=8)
+-- FailT "(3 < 3) | (4 < 3) | (5 < 3) | (6 < 3) | (7 < 3) | (8 < 3) | (9 < 3) | (10 < 3)"
+--
+-- >>> pl @(Map (GuardSimple (Ge 1) >> 'True) Id) [1::Int .. 10]
+-- Present [True,True,True,True,True,True,True,True,True,True] (Map [True,True,True,True,True,True,True,True,True,True] | [1,2,3,4,5,6,7,8,9,10])
+-- PresentT [True,True,True,True,True,True,True,True,True,True]
+--
+data GuardSimple p
+
+instance (Show a
+        , P p a
+        , PP p a ~ Bool
+        ) => P (GuardSimple p) a where
+  type PP (GuardSimple p) a = a
+  eval _ opts a = do
+    let msg0 = "GuardSimple"
+    pp <- evalBool (Proxy @p) (subopts opts) a -- temporarily lift DZero to DLite so as not to lose the failure message
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right False ->
+        let msgx = topMessage pp
+        in mkNode opts (FailT msgx) (msg0 <> " | " <> showL opts a) [hh pp]
+      Right True ->
+        mkNode opts (PresentT a) (msg0 <> "(ok) | " <> showL opts a) [hh pp]
+ src/Predicate/Data/DateTime.hs view
@@ -0,0 +1,599 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted date time functions
+-}
+module Predicate.Data.DateTime (
+
+  -- ** format
+    FormatTimeP
+
+  -- ** constructors
+  , ParseTimeP
+  , ParseTimeP'
+  , ParseTimes
+  , ParseTimes'
+  , MkDay
+  , MkDay'
+  , MkDayExtra
+  , MkDayExtra'
+  , MkTime
+  , MkTime'
+  , PosixToUTCTime
+
+ -- ** destructors
+  , UnMkDay
+  , ToWeekDate
+  , ToWeekYear
+  , ToDay
+  , ToTime
+  , UnMkTime
+  , UTCTimeToPosix
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Control.Lens hiding (iall)
+import Data.Proxy
+import Data.Typeable
+import Data.Kind (Type)
+import Data.Maybe
+import Data.Time
+import Data.Time.Calendar.WeekDate
+import qualified Data.Time.Clock.System as CP
+import qualified Data.Time.Clock.POSIX as P
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+-- >>> import Safe (readNote)
+
+-- | type level expression representing a formatted time
+-- similar to 'Data.Time.formatTime' using a type level 'GHC.TypeLits.Symbol' to get the formatting string
+--
+-- >>> pz @(FormatTimeP "%F %T" Id) (readNote @LocalTime "invalid localtime" "2019-05-24 05:19:59")
+-- PresentT "2019-05-24 05:19:59"
+--
+-- >>> pz @(FormatTimeP (Fst Id) (Snd Id)) ("the date is %d/%m/%Y", readNote @Day "invalid day" "2019-05-24")
+-- PresentT "the date is 24/05/2019"
+--
+-- >>> pl @(FormatTimeP "%Y-%m-%d" Id) (readNote @Day "invalid day" "2019-08-17")
+-- Present "2019-08-17" (FormatTimeP (%Y-%m-%d) 2019-08-17 | 2019-08-17)
+-- PresentT "2019-08-17"
+--
+data FormatTimeP p q
+
+instance (PP p x ~ String
+        , FormatTime (PP q x)
+        , P p x
+        , Show (PP q x)
+        , P q x
+        ) => P (FormatTimeP p q) x where
+  type PP (FormatTimeP p q) x = String
+  eval _ opts x = do
+    let msg0 = "FormatTimeP"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            b = formatTime defaultTimeLocale p q
+        in mkNode opts (PresentT b) (msg1 <> " " <> litL opts b <> showVerbose opts " | " q) [hh pp, hh qq]
+
+-- | similar to 'Data.Time.parseTimeM' where \'t\' is the 'Data.Time.ParseTime' type, \'p\' is the datetime format and \'q\' points to the content to parse
+--
+-- >>> pz @(ParseTimeP LocalTime "%F %T" Id) "2019-05-24 05:19:59"
+-- PresentT 2019-05-24 05:19:59
+--
+-- >>> pz @(ParseTimeP LocalTime "%F %T" "2019-05-24 05:19:59") (Right "never used")
+-- PresentT 2019-05-24 05:19:59
+--
+-- keeping \'q\' as we might want to extract from a tuple
+data ParseTimeP' t p q
+
+instance (ParseTime (PP t a)
+        , Typeable (PP t a)
+        , Show (PP t a)
+        , P p a
+        , P q a
+        , PP p a ~ String
+        , PP q a ~ String
+        ) => P (ParseTimeP' t p q) a where
+  type PP (ParseTimeP' t p q) a = PP t a
+  eval _ opts a = do
+    let msg0 = "ParseTimeP " <> t
+        t = showT @(PP t a)
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case parseTimeM @Maybe @(PP t a) True defaultTimeLocale p q of
+             Just b -> mkNode opts (PresentT b) (lit01 opts msg1 b "fmt=" p <> showVerbose opts " | " q) hhs
+             Nothing -> mkNode opts (FailT (msg1 <> " failed to parse")) "" hhs
+-- | similar to 'Date.Time.parseTimeM'
+--
+-- >>> pl @(ParseTimeP TimeOfDay "%H:%M%S" Id) "14:04:61"
+-- Error ParseTimeP TimeOfDay (%H:%M%S) failed to parse
+-- FailT "ParseTimeP TimeOfDay (%H:%M%S) failed to parse"
+--
+-- >>> pl @(ParseTimeP UTCTime "%F %T" Id) "1999-01-01 12:12:12"
+-- Present 1999-01-01 12:12:12 UTC (ParseTimeP UTCTime (%F %T) 1999-01-01 12:12:12 UTC | fmt=%F %T | "1999-01-01 12:12:12")
+-- PresentT 1999-01-01 12:12:12 UTC
+--
+
+data ParseTimeP (t :: Type) p q
+type ParseTimePT (t :: Type) p q = ParseTimeP' (Hole t) p q
+
+instance P (ParseTimePT t p q) x => P (ParseTimeP t p q) x where
+  type PP (ParseTimeP t p q) x = PP (ParseTimePT t p q) x
+  eval _ = eval (Proxy @(ParseTimePT t p q))
+
+-- | A convenience method to match against many different datetime formats to find the first match
+data ParseTimes' t p q
+
+instance (ParseTime (PP t a)
+        , Typeable (PP t a)
+        , Show (PP t a)
+        , P p a
+        , P q a
+        , PP p a ~ [String]
+        , PP q a ~ String
+        ) => P (ParseTimes' t p q) a where
+  type PP (ParseTimes' t p q) a = PP t a
+  eval _ opts a = do
+    let msg0 = "ParseTimes " <> t
+        t = showT @(PP t a)
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+            zs = map (\d -> (d,) <$> parseTimeM @Maybe @(PP t a) True defaultTimeLocale d q) p
+        in case catMaybes zs of
+             [] -> mkNode opts (FailT ("no match on (" ++ q ++ ")")) msg0 hhs
+             (d,b):_ -> mkNode opts (PresentT b) (lit01 opts msg0 b "fmt=" d <> showVerbose opts " | " q) hhs
+
+-- | A convenience method to match against many different datetime formats to find the first match
+--
+-- >>> pz @(ParseTimes LocalTime '["%Y-%m-%d %H:%M:%S", "%m/%d/%y %H:%M:%S", "%B %d %Y %H:%M:%S", "%Y-%m-%dT%H:%M:%S"] "03/11/19 01:22:33") ()
+-- PresentT 2019-03-11 01:22:33
+--
+-- >>> pz @(ParseTimes LocalTime (Fst Id) (Snd Id)) (["%Y-%m-%d %H:%M:%S", "%m/%d/%y %H:%M:%S", "%B %d %Y %H:%M:%S", "%Y-%m-%dT%H:%M:%S"], "03/11/19 01:22:33")
+-- PresentT 2019-03-11 01:22:33
+--
+-- >>> pl @(Map (ParseTimes Day '["%Y-%m-%d", "%m/%d/%y", "%b %d %Y"] Id) Id) ["2001-01-01", "Jan 24 2009", "03/29/0x7"]
+-- Error no match on (03/29/0x7) (Map(i=2, a="03/29/0x7") excnt=1)
+-- FailT "no match on (03/29/0x7)"
+--
+-- >>> pl @(Map (ParseTimes Day '["%Y-%m-%d", "%m/%d/%y", "%b %d %Y"] Id) Id) ["2001-01-01", "Jan 24 2009", "03/29/07"]
+-- Present [2001-01-01,2009-01-24,2007-03-29] (Map [2001-01-01,2009-01-24,2007-03-29] | ["2001-01-01","Jan 24 2009","03/29/07"])
+-- PresentT [2001-01-01,2009-01-24,2007-03-29]
+--
+data ParseTimes (t :: Type) p q
+type ParseTimesT (t :: Type) p q = ParseTimes' (Hole t) p q
+
+instance P (ParseTimesT t p q) x => P (ParseTimes t p q) x where
+  type PP (ParseTimes t p q) x = PP (ParseTimesT t p q) x
+  eval _ = eval (Proxy @(ParseTimesT t p q))
+
+-- | create a 'Day' from three int values passed in as year month and day
+--
+-- >>> pz @(MkDay' (Fst Id) (Snd Id) (Thd Id)) (2019,99,99999)
+-- PresentT Nothing
+--
+data MkDay' p q r
+
+instance (P p x
+        , P q x
+        , P r x
+        , PP p x ~ Int
+        , PP q x ~ Int
+        , PP r x ~ Int
+        ) => P (MkDay' p q r) x where
+  type PP (MkDay' p q r) x = Maybe Day
+  eval _ opts x = do
+    let msg0 = "MkDay"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        rr <- eval (Proxy @r) opts x
+        pure $ case getValueLR opts msg0 rr hhs of
+          Left e -> e
+          Right r ->
+            let mday = fromGregorianValid (fromIntegral p) q r
+            in mkNode opts (PresentT mday) (show01' opts msg0 mday "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
+
+-- | create a 'Day' from three int values passed in as year month and day
+--
+-- >>> pz @(MkDay '(1,2,3) >> 'Just Id) ()
+-- PresentT 0001-02-03
+--
+-- >>> pz @(Just (MkDay '(1,2,3))) 1
+-- PresentT 0001-02-03
+--
+-- >>> pz @(MkDay Id) (2019,12,30)
+-- PresentT (Just 2019-12-30)
+--
+-- >>> pz @(MkDay Id) (1999,3,13)
+-- PresentT (Just 1999-03-13)
+--
+data MkDay p
+type MkDayT p = MkDay' (Fst p) (Snd p) (Thd p)
+
+instance P (MkDayT p) x => P (MkDay p) x where
+  type PP (MkDay p) x = PP (MkDayT p) x
+  eval _ = eval (Proxy @(MkDayT p))
+
+-- | uncreate a 'Day' returning year month and day
+--
+-- >>> pz @(UnMkDay Id) (readNote "invalid day" "2019-12-30")
+-- PresentT (2019,12,30)
+--
+data UnMkDay p
+
+instance ( PP p x ~ Day
+         , P p x
+         ) => P (UnMkDay p) x where
+  type PP (UnMkDay p) x = (Int, Int, Int)
+  eval _ opts x = do
+    let msg0 = "UnMkDay"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (fromIntegral -> y, m, d) = toGregorian p
+            b = (y, m, d)
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+
+-- | create a 'Day', week number, and the day of the week from three numbers passed in as year month and day
+--
+-- >>> pz @(MkDayExtra' (Fst Id) (Snd Id) (Thd Id)) (2019,99,99999)
+-- PresentT Nothing
+--
+data MkDayExtra' p q r
+
+instance (P p x
+        , P q x
+        , P r x
+        , PP p x ~ Int
+        , PP q x ~ Int
+        , PP r x ~ Int
+        ) => P (MkDayExtra' p q r) x where
+  type PP (MkDayExtra' p q r) x = Maybe (Day, Int, Int)
+  eval _ opts x = do
+    let msg0 = "MkDayExtra"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        rr <- eval (Proxy @r) opts x
+        pure $ case getValueLR opts msg0 rr hhs of
+          Left e -> e
+          Right r ->
+            let mday = fromGregorianValid (fromIntegral p) q r
+                b = mday <&> \day ->
+                      let (_, week, dow) = toWeekDate day
+                      in (day, week, dow)
+            in mkNode opts (PresentT b) (show01' opts msg0 b "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
+
+-- | create a 'Day', week number, and the day of the week from three numbers passed in as year month and day
+--
+-- >>> pz @(MkDayExtra '(1,2,3) >> 'Just Id >> Fst Id) ()
+-- PresentT 0001-02-03
+--
+-- >>> pz @(Fst (Just (MkDayExtra '(1,2,3)))) 1
+-- PresentT 0001-02-03
+--
+-- >>> pz @(MkDayExtra Id) (2019,12,30)
+-- PresentT (Just (2019-12-30,1,1))
+--
+-- >>> pz @(MkDayExtra Id) (1999,3,13)
+-- PresentT (Just (1999-03-13,10,6))
+--
+data MkDayExtra p
+type MkDayExtraT p = MkDayExtra' (Fst p) (Snd p) (Thd p)
+
+instance P (MkDayExtraT p) x => P (MkDayExtra p) x where
+  type PP (MkDayExtra p) x = PP (MkDayExtraT p) x
+  eval _ = eval (Proxy @(MkDayExtraT p))
+
+-- | get the day of the week
+--
+-- >>> pz @(Just (MkDay '(2020,7,11)) >> '(UnMkDay Id, ToWeekYear Id,ToWeekDate Id)) ()
+-- PresentT ((2020,7,11),28,(6,"Saturday"))
+--
+data ToWeekDate p
+
+instance ( P p x
+         , PP p x ~ Day
+         ) => P (ToWeekDate p) x where
+  type PP (ToWeekDate p) x = (Int, String)
+  eval _ opts x = do
+    let msg0 = "ToWeekDate"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (_, _week, dow) = toWeekDate p
+            dowString =
+              case dow of
+                 1 -> "Monday"
+                 2 -> "Tuesday"
+                 3 -> "Wednesday"
+                 4 -> "Thursday"
+                 5 -> "Friday"
+                 6 -> "Saturday"
+                 7 -> "Sunday"
+                 _ -> error $ "oops: ToWeekDate invalid " ++ show dow
+        in mkNode opts (PresentT (dow,dowString)) (show01 opts msg0 dow p) [hh pp]
+
+-- | get week number of the year
+--
+-- >>> pz @(Just (MkDay '(2020,7,11)) >> ToWeekYear Id) ()
+-- PresentT 28
+--
+data ToWeekYear p
+
+instance ( P p x
+         , PP p x ~ Day
+         ) => P (ToWeekYear p) x where
+  type PP (ToWeekYear p) x = Int
+  eval _ opts x = do
+    let msg0 = "ToWeekYear"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (_, week, _dow) = toWeekDate p
+        in mkNode opts (PresentT week) (show01 opts msg0 week p) [hh pp]
+
+class ToDayC a where
+  getDay :: a -> Day
+instance ToDayC UTCTime where
+  getDay = utctDay
+instance ToDayC ZonedTime where
+  getDay = getDay . zonedTimeToLocalTime
+instance ToDayC LocalTime where
+  getDay = localDay
+instance ToDayC Day where
+  getDay = id
+instance ToDayC Rational where
+  getDay = getDay . P.posixSecondsToUTCTime . fromRational
+instance ToDayC CP.SystemTime where
+  getDay = getDay . CP.systemToUTCTime
+
+class ToTimeC a where
+  getTime :: a -> TimeOfDay
+instance ToTimeC UTCTime where
+  getTime = getTime . utctDayTime
+instance ToTimeC ZonedTime where
+  getTime = getTime . zonedTimeToLocalTime
+instance ToTimeC LocalTime where
+  getTime = localTimeOfDay
+instance ToTimeC TimeOfDay where
+  getTime = id
+instance ToTimeC DiffTime where
+  getTime = timeToTimeOfDay
+instance ToTimeC Rational where
+  getTime = getTime . P.posixSecondsToUTCTime . fromRational
+instance ToTimeC CP.SystemTime where
+  getTime = getTime . CP.systemToUTCTime
+
+-- | extract 'Day' from a DateTime
+--
+-- >>> pz @(ReadP UTCTime Id >> ToDay Id) "2020-07-06 12:11:13Z"
+-- PresentT 2020-07-06
+--
+data ToDay p
+
+instance ( P p x
+         , Show (PP p x)
+         , ToDayC (PP p x)
+         ) => P (ToDay p) x where
+  type PP (ToDay p) x = Day
+  eval _ opts x = do
+    let msg0 = "ToDay"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let ret = getDay p
+        in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
+
+-- | extract 'TimeOfDay' from DateTime
+--
+-- >>> pz @(ReadP UTCTime Id >> ToDay Id) "2020-07-06 12:11:13Z"
+-- PresentT 2020-07-06
+--
+data ToTime p
+
+instance ( P p x
+         , Show (PP p x)
+         , ToTimeC (PP p x)
+         ) => P (ToTime p) x where
+  type PP (ToTime p) x = TimeOfDay
+  eval _ opts x = do
+    let msg0 = "ToTime"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let ret = getTime p
+        in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
+
+
+-- | create a 'TimeOfDay' from three int values passed in as year month and day
+--
+-- >>> pz @(MkTime' (Fst Id) (Snd Id) (Thd Id)) (13,99,99999)
+-- PresentT 13:99:99999
+--
+data MkTime' p q r
+
+instance (P p x
+        , P q x
+        , P r x
+        , PP p x ~ Int
+        , PP q x ~ Int
+        , PP r x ~ Rational
+        ) => P (MkTime' p q r) x where
+  type PP (MkTime' p q r) x = TimeOfDay
+  eval _ opts x = do
+    let msg0 = "MkTime"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        rr <- eval (Proxy @r) opts x
+        pure $ case getValueLR opts msg0 rr hhs of
+          Left e -> e
+          Right r ->
+            let mtime = TimeOfDay p q (fromRational r)
+            in mkNode opts (PresentT mtime) (show01' opts msg0 mtime "(h,m,s)=" (p,q,r)) (hhs <> [hh rr])
+
+-- | create a 'TimeOfDay' from a three-tuple of year month and day
+--
+-- >>> pz @(MkTime '(1,2,3 % 12345)) ()
+-- PresentT 01:02:00.000243013365
+--
+-- >>> pz @(MkTime Id) (12,13,65)
+-- PresentT 12:13:65
+--
+-- >>> pz @(MkTime Id) (17,3,13)
+-- PresentT 17:03:13
+--
+data MkTime p
+type MkTimeT p = MkTime' (Fst p) (Snd p) (Thd p)
+
+instance P (MkTimeT p) x => P (MkTime p) x where
+  type PP (MkTime p) x = PP (MkTimeT p) x
+  eval _ = eval (Proxy @(MkTimeT p))
+
+
+-- | uncreate a 'TimeOfDay' returning hour minute seconds picoseconds
+--
+-- >>> pz @(ReadP UTCTime "2019-01-01 12:13:14.1234Z" >> ToTime Id >> UnMkTime Id) ()
+-- PresentT (12,13,70617 % 5000)
+--
+-- >>> pz @(ReadP UTCTime Id >> ToTime Id >> UnMkTime Id) "2020-07-22 08:01:14.127Z"
+-- PresentT (8,1,14127 % 1000)
+--
+-- >>> pz @(ReadP ZonedTime Id >> '(UnMkDay (ToDay Id), UnMkTime (ToTime Id))) "2020-07-11 11:41:12.333 CET"
+-- PresentT ((2020,7,11),(11,41,12333 % 1000))
+--
+data UnMkTime p
+
+instance ( PP p x ~ TimeOfDay
+         , P p x
+         ) => P (UnMkTime p) x where
+  type PP (UnMkTime p) x = (Int, Int, Rational)
+  eval _ opts x = do
+    let msg0 = "UnMkTime"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let TimeOfDay h m s = p
+            b = (h, m, toRational s)
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+
+-- microsoft json date is x*1000 ie milliseconds
+
+-- | convert posix time (seconds since 01-01-1970) to 'UTCTime'
+--
+-- >>> pl @(PosixToUTCTime Id) 1593384312
+-- Present 2020-06-28 22:45:12 UTC (PosixToUTCTime 2020-06-28 22:45:12 UTC | 1593384312 % 1)
+-- PresentT 2020-06-28 22:45:12 UTC
+--
+-- >>> pl @(PosixToUTCTime Id >> UTCTimeToPosix Id) 1593384312
+-- Present 1593384312 % 1 ((>>) 1593384312 % 1 | {UTCTimeToPosix 1593384312 % 1 | 2020-06-28 22:45:12 UTC})
+-- PresentT (1593384312 % 1)
+--
+-- >>> pl @(PosixToUTCTime (Id % 1000)) 1593384312000
+-- Present 2020-06-28 22:45:12 UTC (PosixToUTCTime 2020-06-28 22:45:12 UTC | 1593384312 % 1)
+-- PresentT 2020-06-28 22:45:12 UTC
+--
+-- >>> pl @(PosixToUTCTime Id) (3600*4+60*7+12)
+-- Present 1970-01-01 04:07:12 UTC (PosixToUTCTime 1970-01-01 04:07:12 UTC | 14832 % 1)
+-- PresentT 1970-01-01 04:07:12 UTC
+--
+-- >>> pz @(Rescan "^Date\\((\\d+)([^\\)]+)\\)" Id >> Head Id >> Snd Id >> ReadP Integer (Id !! 0) >> PosixToUTCTime (Id % 1000)) "Date(1530144000000+0530)"
+-- PresentT 2018-06-28 00:00:00 UTC
+--
+data PosixToUTCTime p
+
+instance ( PP p x ~ Rational
+         , P p x
+         ) => P (PosixToUTCTime p) x where
+  type PP (PosixToUTCTime p) x = UTCTime
+  eval _ opts x = do
+    let msg0 = "PosixToUTCTime"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = P.posixSecondsToUTCTime (fromRational p)
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+-- | convert 'UTCTime' to posix time (seconds since 01-01-1970)
+--
+-- >>> pl @(ReadP UTCTime Id >> UTCTimeToPosix Id) "2020-06-28 22:45:12 UTC"
+-- Present 1593384312 % 1 ((>>) 1593384312 % 1 | {UTCTimeToPosix 1593384312 % 1 | 2020-06-28 22:45:12 UTC})
+-- PresentT (1593384312 % 1)
+--
+-- >>> pz @(Rescan "^Date\\((\\d+)([^\\)]+)\\)" Id >> Head Id >> Snd Id >> ((ReadP Integer (Id !! 0) >> PosixToUTCTime (Id % 1000)) &&& ReadP TimeZone (Id !! 1))) "Date(1530144000000+0530)"
+-- PresentT (2018-06-28 00:00:00 UTC,+0530)
+--
+-- not so useful: instead use ParseTimeP FormatTimeP with %s %q %z etc
+--
+-- >>> pz @(ParseTimeP ZonedTime "%s%Q%z" Id)  "153014400.000+0530"
+-- PresentT 1974-11-07 05:30:00 +0530
+--
+data UTCTimeToPosix p
+
+instance ( PP p x ~ UTCTime
+         , P p x
+         ) => P (UTCTimeToPosix p) x where
+  type PP (UTCTimeToPosix p) x = Rational
+  eval _ opts x = do
+    let msg0 = "UTCTimeToPosix"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = toRational $ P.utcTimeToPOSIXSeconds p
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+ src/Predicate/Data/Either.hs view
@@ -0,0 +1,644 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted 'Either' functions
+-}
+module Predicate.Data.Either (
+
+ -- ** boolean predicates
+    IsLeft
+  , IsRight
+
+ -- ** constructors
+  , MkLeft
+  , MkLeft'
+  , MkRight
+  , MkRight'
+
+ -- ** get rid of Either
+  , Left'
+  , Right'
+  , LeftDef
+  , LeftFail
+  , RightDef
+  , RightFail
+  , EitherBool
+  , EitherIn
+  , PartitionEithers
+
+ -- ** miscellaneous
+  , type (|||)
+  , type (+++)
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import GHC.TypeLits (ErrorMessage((:$$:),(:<>:)))
+import qualified GHC.TypeLits as GL
+import Data.Proxy
+import Data.Kind (Type)
+import Data.Either
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+
+-- | extracts the left value from an 'Either'
+--
+-- >>> pz @(Left' >> Succ Id) (Left 20)
+-- PresentT 21
+--
+-- >>> pz @(Left' >> Succ Id) (Right 'a')
+-- FailT "Left' found Right"
+--
+data Left'
+instance (Show a
+        ) => P Left' (Either a x) where
+  type PP Left' (Either a x) = a
+  eval _ opts lr =
+    let msg0 = "Left'"
+    in pure $ case lr of
+         Right _ -> mkNode opts (FailT (msg0 <> " found Right")) "" []
+         Left a -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | extracts the right value from an 'Either'
+--
+-- >>> pz @(Right' >> Succ Id) (Right 20)
+-- PresentT 21
+--
+-- >>> pz @(Right' >> Succ Id) (Left 'a')
+-- FailT "Right' found Left"
+--
+data Right'
+instance (Show a
+        ) => P Right' (Either x a) where
+  type PP Right' (Either x a) = a
+  eval _ opts lr =
+    let msg0 = "Right'"
+    in pure $ case lr of
+         Left _ -> mkNode opts (FailT (msg0 <> " found Left")) "" []
+         Right a -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | similar 'Control.Arrow.|||'
+--
+-- >>> pz @(Pred Id ||| Id) (Left 13)
+-- PresentT 12
+--
+-- >>> pz @(ShowP Id ||| Id) (Right "hello")
+-- PresentT "hello"
+--
+-- >>> pl @('True ||| 'False) (Left "someval")
+-- True ((|||) Left True | "someval")
+-- TrueT
+--
+-- >>> pl @('True ||| 'False) (Right "someval")
+-- False ((|||) Right False | "someval")
+-- FalseT
+--
+-- >>> pl @(ShowP (Succ Id) ||| ShowP Id) (Left 123)
+-- Present "124" ((|||) Left "124" | 123)
+-- PresentT "124"
+--
+-- >>> pl @(ShowP (Succ Id) ||| ShowP Id) (Right True)
+-- Present "True" ((|||) Right "True" | True)
+-- PresentT "True"
+--
+-- >>> pl @(EitherIn (Not Id) Id) (Right True)
+-- Present True ((|||) Right True | True)
+-- PresentT True
+--
+-- >>> pl @(EitherIn (Not Id) Id) (Left True)
+-- False ((|||) Left False | True)
+-- FalseT
+--
+data p ||| q
+infixr 2 |||
+type EitherIn p q = p ||| q
+
+instance (Show (PP p a)
+        , P p a
+        , P q b
+        , PP p a ~ PP q b
+        , Show a
+        , Show b
+        ) => P (p ||| q) (Either a b) where
+  type PP (p ||| q) (Either a b) = PP p a
+  eval _ opts lr = do
+    let msg0 = "(|||)"
+    case lr of
+      Left a -> do
+        pp <- eval (Proxy @p) opts a
+        pure $ case getValueLR opts msg0 pp [] of
+          Left e -> e
+          Right a1 -> let msg1 = msg0 ++ " Left"
+                      in mkNode opts (_tBool pp) (show01 opts msg1 a1 a) [hh pp]
+      Right a -> do
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg0 qq [] of
+          Left e -> e
+          Right a1 ->
+            let msg1 = msg0 ++ " Right"
+            in mkNode opts (_tBool qq) (show01 opts msg1 a1 a) [hh qq]
+
+-- | similar to 'isLeft'
+--
+-- >>> pz @(IsLeft Id) (Right 123)
+-- FalseT
+--
+-- >>> pz @(IsLeft Id) (Left 'a')
+-- TrueT
+--
+data IsLeft p
+
+instance ( P p x
+         , PP p x ~ Either a b
+         ) => P (IsLeft p) x where
+  type PP (IsLeft p) x = Bool
+  eval _ opts x = do
+    let msg0 = "IsLeft"
+    pp <- eval (Proxy @p) opts x
+    let hhs = [hh pp]
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right (Left _) -> mkNodeB opts True msg0 hhs
+      Right (Right _) -> mkNodeB opts False msg0 hhs
+
+-- | similar to 'isRight'
+--
+-- >>> pz @(IsRight Id) (Right 123)
+-- TrueT
+--
+-- >>> pz @(IsRight Id) (Left "aa")
+-- FalseT
+--
+data IsRight p
+
+instance ( P p x
+         , PP p x ~ Either a b
+         ) => P (IsRight p) x where
+  type PP (IsRight p) x = Bool
+  eval _ opts x = do
+    let msg0 = "IsRight"
+    pp <- eval (Proxy @p) opts x
+    let hhs = [hh pp]
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right (Left _) -> mkNodeB opts False msg0 hhs
+      Right (Right _) -> mkNodeB opts True msg0 hhs
+
+
+-- | similar 'Control.Arrow.+++'
+--
+-- >>> pz @(Pred Id +++ Id) (Left 13)
+-- PresentT (Left 12)
+--
+-- >>> pz @(ShowP Id +++ Reverse) (Right "hello")
+-- PresentT (Right "olleh")
+--
+-- >>> pl @(HeadDef 'False Id +++ Id) (Right @[Bool] 1) -- need @[Bool] cos we said 'False!
+-- Present Right 1 ((+++) Right 1 | 1)
+-- PresentT (Right 1)
+--
+-- >>> pl @(HeadDef 'False Id +++ Id) (Left [True,False]) -- need @[Bool] cos we said 'False!
+-- Present Left True ((+++) Left True | [True,False])
+-- PresentT (Left True)
+--
+-- >>> pl @(Not Id +++ Id) (Right True)
+-- Present Right True ((+++) Right True | True)
+-- PresentT (Right True)
+--
+-- >>> pl @(Not Id +++ Id) (Right 12)
+-- Present Right 12 ((+++) Right 12 | 12)
+-- PresentT (Right 12)
+--
+-- >>> pl @(HeadDef () Id +++ Id) (Right @[()] 1) -- breaks otherwise: Id says () -> () so has to be a list of [()]
+-- Present Right 1 ((+++) Right 1 | 1)
+-- PresentT (Right 1)
+--
+-- >>> pl @(HeadDef () Id +++ Id) (Right @[()] 1) -- this breaks! cos Left doesnt have a type
+-- Present Right 1 ((+++) Right 1 | 1)
+-- PresentT (Right 1)
+--
+-- >>> pl @(Not Id +++ Id) (Right @Bool 12)
+-- Present Right 12 ((+++) Right 12 | 12)
+-- PresentT (Right 12)
+--
+data p +++ q
+infixr 2 +++
+
+instance (Show (PP p a)
+        , Show (PP q b)
+        , P p a
+        , P q b
+        , Show a
+        , Show b
+        ) => P (p +++ q) (Either a b) where
+  type PP (p +++ q) (Either a b) = Either (PP p a) (PP q b)
+  eval _ opts lr = do
+    let msg0 = "(+++)"
+    case lr of
+      Left a -> do
+        pp <- eval (Proxy @p) opts a
+        pure $ case getValueLR opts msg0 pp [] of
+          Left e -> e
+          Right a1 ->
+            let msg1 = msg0 ++ " Left"
+            in mkNode opts (PresentT (Left a1)) (msg1 <> " " <> showL opts a1 <> showVerbose opts " | " a) [hh pp]
+      Right a -> do
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg0 qq [] of
+          Left e -> e
+          Right a1 ->
+            let msg1 = msg0 ++ " Right"
+            in mkNode opts (PresentT (Right a1)) (msg1 <> " " <> showL opts a1 <> showVerbose opts " | " a) [hh qq]
+
+-- | similar to 'partitionEithers'
+--
+-- >>> pz @PartitionEithers [Left 'a',Right 2,Left 'c',Right 4,Right 99]
+-- PresentT ("ac",[2,4,99])
+--
+-- >>> pz @PartitionEithers [Right 2,Right 4,Right 99]
+-- PresentT ([],[2,4,99])
+--
+-- >>> pz @PartitionEithers [Left 'a',Left 'c']
+-- PresentT ("ac",[])
+--
+-- >>> pz @PartitionEithers ([] :: [Either () Int])
+-- PresentT ([],[])
+--
+-- >>> pl @PartitionEithers [Left 4, Right 'x', Right 'y',Left 99]
+-- Present ([4,99],"xy") (PartitionEithers ([4,99],"xy") | [Left 4,Right 'x',Right 'y',Left 99])
+-- PresentT ([4,99],"xy")
+--
+-- >>> pl @PartitionEithers [Left 'x', Right 1,Left 'a', Left 'b',Left 'z', Right 10]
+-- Present ("xabz",[1,10]) (PartitionEithers ("xabz",[1,10]) | [Left 'x',Right 1,Left 'a',Left 'b',Left 'z',Right 10])
+-- PresentT ("xabz",[1,10])
+--
+data PartitionEithers
+
+instance ( Show a
+         , Show b
+         ) => P PartitionEithers [Either a b] where
+  type PP PartitionEithers [Either a b] = ([a], [b])
+  eval _ opts as =
+    let msg0 = "PartitionEithers"
+        b = partitionEithers as
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | Convenient method to convert a \'p\' or \'q\' to a 'Either' based on a predicate \'b\'
+--   if \'b\' then Right \'p\' else Left \'q\'
+--
+-- >>> pz @(EitherBool (Fst Id > 4) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (24,(-1,999))
+-- PresentT (Right 999)
+--
+-- >>> pz @(EitherBool (Fst Id > 4) (Fst (Snd Id)) (Snd (Snd Id))) (1,(-1,999))
+-- PresentT (Left (-1))
+--
+-- >>> pl @(EitherBool (Fst Id > 10) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (7,('x',99))
+-- Present Left 'x' (EitherBool(False) Left 'x')
+-- PresentT (Left 'x')
+--
+-- >>> pl @(EitherBool (Fst Id > 10) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (11,('x',99))
+-- Present Right 99 (EitherBool(True) Right 99)
+-- PresentT (Right 99)
+--
+-- >>> pl @(EitherBool (Gt 10) "found left" 99) 12
+-- Present Right 99 (EitherBool(True) Right 99)
+-- PresentT (Right 99)
+--
+-- >>> pl @(EitherBool (Gt 10) "found left" 99) 7
+-- Present Left "found left" (EitherBool(False) Left "found left")
+-- PresentT (Left "found left")
+--
+data EitherBool b p q
+
+instance (Show (PP p a)
+        , P p a
+        , Show (PP q a)
+        , P q a
+        , P b a
+        , PP b a ~ Bool
+        ) => P (EitherBool b p q) a where
+  type PP (EitherBool b p q) a = Either (PP p a) (PP q a)
+  eval _ opts z = do
+    let msg0 = "EitherBool"
+    bb <- evalBool (Proxy @b) opts z
+    case getValueLR opts (msg0 <> " b failed") bb [] of
+      Left e -> pure e
+      Right False -> do
+        pp <- eval (Proxy @p) opts z
+        pure $ case getValueLR opts (msg0 <> " p failed") pp [hh bb] of
+          Left e -> e
+          Right p -> mkNode opts (PresentT (Left p)) (msg0 <> "(False) Left " <> showL opts p) [hh bb, hh pp]
+      Right True -> do
+        qq <- eval (Proxy @q) opts z
+        pure $ case getValueLR opts (msg0 <> " q failed") qq [hh bb] of
+          Left e -> e
+          Right q -> mkNode opts (PresentT (Right q)) (msg0 <> "(True) Right " <> showL opts q) [hh bb, hh qq]
+
+-- | similar to 'Control.Arrow.|||' but additionally gives \'p\' and \'q\' the original input
+--
+-- >>> pz @(EitherX (ShowP (Fst (Fst Id) + Snd Id)) (ShowP Id) (Snd Id)) (9,Left 123)
+-- PresentT "132"
+--
+-- >>> pz @(EitherX (ShowP (Fst (Fst Id) + Snd Id)) (ShowP Id) (Snd Id)) (9,Right 'x')
+-- PresentT "((9,Right 'x'),'x')"
+--
+-- >>> pz @(EitherX (ShowP Id) (ShowP (Second (Succ Id))) (Snd Id)) (9,Right 'x')
+-- PresentT "((9,Right 'x'),'y')"
+--
+data EitherX p q r
+instance (P r x
+        , P p (x,a)
+        , P q (x,b)
+        , PP r x ~ Either a b
+        , PP p (x,a) ~ c
+        , PP q (x,b) ~ c
+        ) => P (EitherX p q r) x where
+  type PP (EitherX p q r) x = EitherXT (PP r x) x p
+  eval _ opts x = do
+    let msg0 = "EitherX"
+    rr <- eval (Proxy @r) opts x
+    case getValueLR opts msg0 rr [] of
+      Left e -> pure e
+      Right (Left a) -> do
+        let msg1 = msg0 <> "(Left)"
+        pp <- eval (Proxy @p) opts (x,a)
+        pure $ case getValueLR opts msg1 pp [hh rr] of
+          Left e -> e
+          Right _ -> mkNode opts (_tBool pp) msg1 [hh rr, hh pp]
+      Right (Right b) -> do
+        let msg1 = msg0 <> "(Right)"
+        qq <- eval (Proxy @q) opts (x,b)
+        pure $ case getValueLR opts msg1 qq [hh rr] of
+          Left e -> e
+          Right _ -> mkNode opts (_tBool qq) msg1 [hh rr, hh qq]
+
+type family EitherXT lr x p where
+  EitherXT (Either a b) x p = PP p (x,a)
+  EitherXT o _ _ = GL.TypeError (
+      'GL.Text "EitherXT: expected 'Either a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+-- | 'Data.Either.Left' constructor
+data MkLeft' t p
+
+instance ( Show (PP p x)
+         , P p x
+         ) => P (MkLeft' t p) x where
+  type PP (MkLeft' t p) x = Either (PP p x) (PP t x)
+  eval _ opts x = do
+    let msg0 = "MkLeft"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = Left p
+        in mkNode opts (PresentT d) (msg0 <> " Left " <> showL opts p) [hh pp]
+
+-- | 'Data.Either.Left' constructor
+--
+-- >>> pz @(MkLeft _ Id) 44
+-- PresentT (Left 44)
+--
+data MkLeft (t :: Type) p
+type MkLeftT (t :: Type) p = MkLeft' (Hole t) p
+
+instance P (MkLeftT t p) x => P (MkLeft t p) x where
+  type PP (MkLeft t p) x = PP (MkLeftT t p) x
+  eval _ = eval (Proxy @(MkLeftT t p))
+
+-- | 'Data.Either.Right' constructor
+data MkRight' t p
+
+instance ( Show (PP p x)
+         , P p x
+         ) => P (MkRight' t p) x where
+  type PP (MkRight' t p) x = Either (PP t x) (PP p x)
+  eval _ opts x = do
+    let msg0 = "MkRight"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = Right p
+        in mkNode opts (PresentT d) (msg0 <> " Right " <> showL opts p) [hh pp]
+
+-- | 'Data.Either.Right' constructor
+--
+-- >>> pz @(MkRight _ Id) 44
+-- PresentT (Right 44)
+--
+data MkRight (t :: Type) p
+type MkRightT (t :: Type) p = MkRight' (Hole t) p
+
+instance P (MkRightT t p) x => P (MkRight t p) x where
+  type PP (MkRight t p) x = PP (MkRightT t p) x
+  eval _ = eval (Proxy @(MkRightT t p))
+
+-- | extract the Left value from an 'Either' otherwise use the default value: similar to 'Data.Either.fromLeft'
+--
+-- if there is no Left value then \p\ is passed the Right value and the whole context
+--
+-- >>> pz @(LeftDef (1 % 4) Id) (Left 20.4)
+-- PresentT (102 % 5)
+--
+-- >>> pz @(LeftDef (1 % 4) Id) (Right "aa")
+-- PresentT (1 % 4)
+--
+-- >>> pz @(LeftDef (PrintT "found right=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Right "xy")
+-- PresentT "found right=xy fst=123"
+--
+-- >>> pz @(LeftDef (MEmptyT _) Id) (Right 222)
+-- PresentT ()
+--
+-- >>> pz @(LeftDef (MEmptyT (SG.Sum _)) Id) (Right 222)
+-- PresentT (Sum {getSum = 0})
+--
+data LeftDef p q
+
+instance ( PP q x ~ Either a b
+         , PP p (b,x) ~ a
+         , P q x
+         , P p (b,x)
+    ) => P (LeftDef p q) x where
+  type PP (LeftDef p q) x = LeftT (PP q x)
+  eval _ opts x = do
+    let msg0 = "LeftDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Left a -> pure $ mkNode opts (PresentT a) (msg0 <> " Left") [hh qq]
+          Right b -> do
+            pp <- eval (Proxy @p) opts (b,x)
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (PresentT p) (msg0 <> " Right") [hh qq, hh pp]
+
+-- | extract the Right value from an 'Either': similar to 'Data.Either.fromRight'
+--
+-- if there is no Right value then \p\ is passed the Left value and the whole context
+--
+-- >>> pz @(RightDef (1 % 4) Id) (Right 20.4)
+-- PresentT (102 % 5)
+--
+-- >>> pz @(RightDef (1 % 4) Id) (Left "aa")
+-- PresentT (1 % 4)
+--
+-- >>> pz @(RightDef (PrintT "found left=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Left "xy")
+-- PresentT "found left=xy fst=123"
+--
+-- >>> pz @(RightDef (MEmptyT _) Id) (Left 222)
+-- PresentT ()
+--
+-- >>> pz @(RightDef (MEmptyT (SG.Sum _)) Id) (Left 222)
+-- PresentT (Sum {getSum = 0})
+--
+data RightDef p q
+
+instance ( PP q x ~ Either a b
+         , PP p (a,x) ~ b
+         , P q x
+         , P p (a,x)
+    ) => P (RightDef p q) x where
+  type PP (RightDef p q) x = RightT (PP q x)
+  eval _ opts x = do
+    let msg0 = "RightDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Right b -> pure $ mkNode opts (PresentT b) (msg0 <> " Right") [hh qq]
+          Left a -> do
+            pp <- eval (Proxy @p) opts (a,x)
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (PresentT p) (msg0 <> " Left") [hh qq, hh pp]
+
+
+-- | extract the Left value from an 'Either' otherwise fail with a message
+--
+-- if there is no Left value then \p\ is passed the Right value and the whole context
+--
+-- >>> pz @(LeftFail "oops" Id) (Left 20.4)
+-- PresentT 20.4
+--
+-- >>> pz @(LeftFail "oops" Id) (Right "aa")
+-- FailT "oops"
+--
+-- >>> pz @(LeftFail (PrintT "found right=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Right "xy")
+-- FailT "found right=xy fst=123"
+--
+-- >>> pz @(LeftFail (MEmptyT _) Id) (Right 222)
+-- FailT ""
+--
+-- >>> pl @(LeftFail (PrintF "someval=%d" (Fst (Snd Id))) (Snd Id)) (13::Int,Right @(SG.Sum Int) "abc")
+-- Error someval=13 (LeftFail Right)
+-- FailT "someval=13"
+--
+-- >>> pl @(LeftFail (PrintF "someval=%s" (Fst Id)) Id) (Right @(SG.Sum Int) ("abc" :: String))
+-- Error someval=abc (LeftFail Right)
+-- FailT "someval=abc"
+--
+-- >>> pl @(LeftFail (PrintF "found rhs=%d" (Fst Id)) Id) (Right @String @Int 10)
+-- Error found rhs=10 (LeftFail Right)
+-- FailT "found rhs=10"
+--
+-- >>> pl @(LeftFail (PrintF "found rhs=%d" (Snd Id >> Snd Id >> Snd Id)) (Snd Id >> Fst Id)) ('x',(Right 10,23::Int))
+-- Error found rhs=23 (LeftFail Right)
+-- FailT "found rhs=23"
+--
+-- >>> pl @(LeftFail (PrintF "found rhs=%d" (Snd (Snd (Snd Id)))) (Fst (Snd Id))) ('x',(Left "abc",23::Int))
+-- Present "abc" (Left)
+-- PresentT "abc"
+--
+data LeftFail p q
+
+instance ( PP p (b,x) ~ String
+         , PP q x ~ Either a b
+         , P p (b,x)
+         , P q x)
+    => P (LeftFail p q) x where
+  type PP (LeftFail p q) x = LeftT (PP q x)
+  eval _ opts x = do
+    let msg0 = "LeftFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Left a -> pure $ mkNode opts (PresentT a) "Left" [hh qq]
+          Right b -> do
+            pp <- eval (Proxy @p) opts (b,x)
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " Right") [hh qq, hh pp]
+
+
+-- | extract the Right value from an 'Either' otherwise fail with a message
+--
+-- if there is no Right value then \p\ is passed the Left value and the whole context
+--
+-- >>> pz @(RightFail "oops" Id) (Right 20.4)
+-- PresentT 20.4
+--
+-- >>> pz @(RightFail "oops" Id) (Left "aa")
+-- FailT "oops"
+--
+-- >>> pz @(RightFail (PrintT "found left=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Left "xy")
+-- FailT "found left=xy fst=123"
+--
+-- >>> pz @(RightFail (MEmptyT _) Id) (Left 222)
+-- FailT ""
+--
+data RightFail p q
+
+instance ( PP p (a,x) ~ String
+         , PP q x ~ Either a b
+         , P p (a,x)
+         , P q x)
+    => P (RightFail p q) x where
+  type PP (RightFail p q) x = RightT (PP q x)
+  eval _ opts x = do
+    let msg0 = "RightFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Right b -> pure $ mkNode opts (PresentT b) "Right" [hh qq]
+          Left a -> do
+            pp <- eval (Proxy @p) opts (a,x)
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " Left") [hh qq, hh pp]
+ src/Predicate/Data/Enum.hs view
@@ -0,0 +1,512 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted enum functions
+-}
+module Predicate.Data.Enum (
+
+  -- *** constructors
+    type (...)
+  , EnumFromTo
+  , EnumFromThenTo
+  , FromEnum
+
+  -- ** bounded enums
+  , SuccB
+  , SuccB'
+  , PredB
+  , PredB'
+  , ToEnumBDef
+  , ToEnumBDef'
+  , ToEnumBFail
+
+  -- ** unsafe enum expressions
+  , Succ
+  , SuccN
+  , Pred
+  , ToEnum
+  , ToEnum'
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Safe (succMay, predMay, toEnumMay)
+import Data.Proxy
+import qualified Control.Exception as E
+import Data.Kind (Type)
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.Time
+
+instance (PP q x ~ a
+        , P q x
+        , P p (Proxy a)
+        , PP p (Proxy a) ~ a
+        , Show a
+        , Eq a
+        , Bounded a
+        , Enum a
+        ) => P (SuccB p q) x where
+  type PP (SuccB p q) x = PP q x
+  eval _ opts x = do
+    let msg0 = "SuccB"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case succMay q of
+          Nothing -> do
+             let msg1 = msg0 <> " out of range"
+             pp <- eval (Proxy @p) opts (Proxy @a)
+             pure $ case getValueLR opts msg1 pp [hh qq] of
+               Left e -> e
+               Right _ -> mkNode opts (_tBool pp) msg1 [hh qq, hh pp]
+          Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n q) [hh qq]
+
+-- | bounded 'succ' function
+--
+-- >>> pz @(SuccB 'LT Id) GT
+-- PresentT LT
+--
+data SuccB p q
+
+-- | bounded 'succ' function
+--
+-- >>> pz @(SuccB' Id) GT
+-- FailT "Succ bounded"
+--
+-- >>> pz @(SuccB' Id) (13 :: Int)
+-- PresentT 14
+--
+-- >>> pz @(SuccB' Id) LT
+-- PresentT EQ
+--
+data SuccB' q
+type SuccBT' q = SuccB (Failp "Succ bounded") q
+
+instance P (SuccBT' q) x => P (SuccB' q) x where
+  type PP (SuccB' q) x = PP (SuccBT' q) x
+  eval _ = eval (Proxy @(SuccBT' q))
+
+-- | bounded 'pred' function
+--
+-- >>> pz @(PredB' Id) (13 :: Int)
+-- PresentT 12
+--
+-- >>> pz @(PredB' Id) LT
+-- FailT "Pred bounded"
+--
+-- >>> pl @(PredB' Id) GT
+-- Present EQ (PredB EQ | GT)
+-- PresentT EQ
+--
+-- >>> pl @(PredB' Id) LT
+-- Error Pred bounded (PredB out of range)
+-- FailT "Pred bounded"
+--
+
+data PredB' q
+type PredBT' q = PredB (Failp "Pred bounded") q
+
+instance (PP q x ~ a
+        , P q x
+        , P p (Proxy a)
+        , PP p (Proxy a) ~ a
+        , Show a
+        , Eq a
+        , Bounded a
+        , Enum a
+        ) => P (PredB p q) x where
+  type PP (PredB p q) x = PP q x
+  eval _ opts x = do
+    let msg0 = "PredB"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case predMay q of
+          Nothing -> do
+             let msg1 = msg0 <> " out of range"
+             pp <- eval (Proxy @p) opts (Proxy @a)
+             pure $ case getValueLR opts msg1 pp [hh qq] of
+               Left e -> e
+               Right _ -> mkNode opts (_tBool pp) msg1 [hh qq, hh pp]
+          Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n q) [hh qq]
+
+
+-- | unbounded 'succ' function
+--
+-- >>> pz @(Succ Id) 13
+-- PresentT 14
+--
+-- >>> pz @(Succ Id) LT
+-- PresentT EQ
+--
+-- >>> pz @(Succ Id) GT
+-- FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument"
+--
+-- >>> pl @(Succ Id) 10
+-- Present 11 (Succ 11 | 10)
+-- PresentT 11
+--
+-- >>> pl @(Succ Id) True -- captures the exception
+-- Error Succ IO e=Prelude.Enum.Bool.succ: bad argument (True)
+-- FailT "Succ IO e=Prelude.Enum.Bool.succ: bad argument"
+--
+data Succ p
+
+instance (Show a
+        , Enum a
+        , PP p x ~ a
+        , P p x
+        ) => P (Succ p) x where
+  type PP (Succ p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Succ"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        lr <- catchit @_ @E.SomeException (succ p)
+        pure $ case lr of
+          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (showL opts p) [hh pp]
+          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
+
+-- | SuccN n p (unsafe) increments an enum p by the given integral n
+--
+-- >>> pz @(ReadP Day Id >> Id ... SuccN 5 Id) "2020-07-27"
+-- PresentT [2020-07-27,2020-07-28,2020-07-29,2020-07-30,2020-07-31,2020-08-01]
+--
+-- >>> pz @(ReadP Day Id >> SuccN (Negate 5) Id) "2020-07-27"
+-- PresentT 2020-07-22
+--
+-- >>> pl @(SuccN 3 'LT) ()
+-- Error SuccN IO e=Prelude.Enum.Ordering.toEnum: bad argument (SuccN 3 LT)
+-- FailT "SuccN IO e=Prelude.Enum.Ordering.toEnum: bad argument"
+--
+-- >>> pz @(SuccN 2 'LT) ()
+-- PresentT GT
+--
+data SuccN n p
+
+instance (Show a
+        , Enum a
+        , Integral (PP n x)
+        , P n x
+        , PP p x ~ a
+        , P p x
+        ) => P (SuccN n p) x where
+  type PP (SuccN n p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "SuccN"
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts x []
+    case lr of
+      Left e -> pure e
+      Right (n,p,nn,pp) -> do
+        lr1 <- catchit @_ @E.SomeException (toEnum (fromEnum p + fromIntegral n))
+        pure $ case lr1 of
+          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (litL opts (msg0 <> " " <> show (fromIntegral @_ @Integer n) <> " " <> show p)) [hh nn, hh pp]
+          Right r -> mkNode opts (PresentT r) (litL opts (msg0 <> " " <> show (fromIntegral @_ @Integer n) <> " " <> show p)) [hh nn, hh pp]
+
+
+-- | unbounded 'pred' function
+--
+-- >>> pz @(Pred Id) 13
+-- PresentT 12
+--
+-- >>> pz @(Pred Id) LT
+-- FailT "Pred IO e=Prelude.Enum.Ordering.pred: bad argument"
+--
+data Pred p
+
+instance (Show a
+        , Enum a
+        , PP p x ~ a
+        , P p x
+        ) => P (Pred p) x where
+  type PP (Pred p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Pred"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        lr <- catchit @_ @E.SomeException (pred p)
+        pure $ case lr of
+          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (showL opts p) [hh pp]
+          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
+
+-- | bounded 'pred' function
+--
+-- >>> pl @(PredB 'GT Id) LT
+-- Present GT (PredB out of range)
+-- PresentT GT
+--
+-- >>> pl @(PredB 'LT Id) GT
+-- Present EQ (PredB EQ | GT)
+-- PresentT EQ
+--
+
+data PredB p q
+
+instance P (PredBT' q) x => P (PredB' q) x where
+  type PP (PredB' q) x = PP (PredBT' q) x
+  eval _ = eval (Proxy @(PredBT' q))
+
+
+-- | 'fromEnum' function
+--
+-- >>> pz @(FromEnum Id) 'x'
+-- PresentT 120
+--
+-- >>> pl @(FromEnum ("aa" ==! Id) >> Same 1) "aaaa"
+-- False ((>>) False | {0 == 1})
+-- FalseT
+--
+-- >>> pl @(FromEnum ("aa" ==! Id) >> ToEnum OrderingP Id) "aaaa"
+-- Present CGt ((>>) CGt | {ToEnum CGt | 0})
+-- PresentT CGt
+--
+-- >>> pl @(Map (FromEnum Id) Id >> Map (ToEnum Char Id) Id) ("abcd" :: String)
+-- Present "abcd" ((>>) "abcd" | {Map "abcd" | [97,98,99,100]})
+-- PresentT "abcd"
+--
+
+data FromEnum p
+
+instance (Show a
+        , Enum a
+        , PP p x ~ a
+        , P p x
+        ) => P (FromEnum p) x where
+  type PP (FromEnum p) x = Int
+  eval _ opts x = do
+    let msg0 = "FromEnum"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let n = fromEnum p
+        in mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
+
+-- | unsafe 'toEnum' function
+--
+-- >>> pz @(ToEnum Char Id) 120
+-- PresentT 'x'
+--
+-- >>> pl @(Map (FromEnum Id) Id >> Map (Id - 97 >> ToEnum Ordering Id) Id) ("abcde" :: String)
+-- Error ToEnum IO e=Prelude.Enum.Ordering.toEnum: bad argument(2) ([97,98,99,100,101] (>>) rhs failed)
+-- FailT "ToEnum IO e=Prelude.Enum.Ordering.toEnum: bad argument(2)"
+--
+-- >>> pl @((ToEnum Day Id *** ToEnum Day Id) >> EnumFromTo (Fst Id) (Snd Id)) (0,5)
+-- Present [1858-11-17,1858-11-18,1858-11-19,1858-11-20,1858-11-21,1858-11-22] ((>>) [1858-11-17,1858-11-18,1858-11-19,1858-11-20,1858-11-21,1858-11-22] | {1858-11-17 ... 1858-11-22})
+-- PresentT [1858-11-17,1858-11-18,1858-11-19,1858-11-20,1858-11-21,1858-11-22]
+--
+data ToEnum' t p
+
+instance (PP p x ~ a
+        , P p x
+        , Show a
+        , Enum (PP t x)
+        , Show (PP t x)
+        , Integral a
+        ) => P (ToEnum' t p) x where
+  type PP (ToEnum' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "ToEnum"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        lr <- catchit @_ @E.SomeException (toEnum $! fromIntegral p)
+        pure $ case lr of
+          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (showL opts p) [hh pp]
+          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
+
+data ToEnum (t :: Type) p
+type ToEnumT (t :: Type) p = ToEnum' (Hole t) p
+
+instance P (ToEnumT t p) x => P (ToEnum t p) x where
+  type PP (ToEnum t p) x = PP (ToEnumT t p) x
+  eval _ = eval (Proxy @(ToEnumT t p))
+data ToEnumBDef' t def
+
+instance (P def (Proxy (PP t a))
+        , PP def (Proxy (PP t a)) ~ PP t a
+        , Show a
+        , Show (PP t a)
+        , Bounded (PP t a)
+        , Enum (PP t a)
+        , Integral a
+        ) => P (ToEnumBDef' t def) a where
+  type PP (ToEnumBDef' t def) a = PP t a
+  eval _ opts a = do
+    let msg0 = "ToEnumBDef"
+    case toEnumMay $ fromIntegral a of
+      Nothing -> do
+         let msg1 = msg0 <> " out of range"
+         pp <- eval (Proxy @def) opts (Proxy @(PP t a))
+         pure $ case getValueLR opts msg1 pp [] of
+           Left e -> e
+           Right _ -> mkNode opts (_tBool pp) msg1 [hh pp]
+      Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n a) []
+
+-- | bounded 'toEnum' function
+--
+-- >>> pz @(ToEnumBDef Ordering LT) 2
+-- PresentT GT
+--
+-- >>> pz @(ToEnumBDef Ordering LT) 6
+-- PresentT LT
+--
+-- >>> pl @(ToEnumBDef Ordering 'LT) 123
+-- Present LT (ToEnumBDef out of range)
+-- PresentT LT
+--
+-- >>> pl @(ToEnumBDef Ordering 'GT) 1
+-- Present EQ (ToEnumBDef EQ | 1)
+-- PresentT EQ
+--
+
+data ToEnumBDef (t :: Type) def
+type ToEnumBDefT (t :: Type) def = ToEnumBDef' (Hole t) def
+
+instance P (ToEnumBDefT t def) x => P (ToEnumBDef t def) x where
+  type PP (ToEnumBDef t def) x = PP (ToEnumBDefT t def) x
+  eval _ = eval (Proxy @(ToEnumBDefT t def))
+
+-- | bounded 'toEnum' function
+--
+-- >>> pz @(ToEnumBFail Ordering) 6
+-- FailT "ToEnum bounded"
+--
+-- >>> pl @(ToEnumBFail Ordering) 1
+-- Present EQ (ToEnumBDef EQ | 1)
+-- PresentT EQ
+--
+-- >>> pl @(ToEnumBFail Ordering) 44
+-- Error ToEnum bounded (ToEnumBDef out of range)
+-- FailT "ToEnum bounded"
+--
+data ToEnumBFail (t :: Type)
+type ToEnumBFailT (t :: Type) = ToEnumBDef' (Hole t) (Failp "ToEnum bounded")
+
+instance P (ToEnumBFailT t) x => P (ToEnumBFail t) x where
+  type PP (ToEnumBFail t) x = PP (ToEnumBFailT t) x
+  eval _ = eval (Proxy @(ToEnumBFailT t))
+
+-- | similar to 'enumFromTo'
+--
+-- >>> pz @(EnumFromTo 'GT 'LT) ()
+-- PresentT []
+--
+-- >>> pz @(EnumFromTo (Pred Id) (Succ Id)) (SG.Max 10)
+-- PresentT [Max {getMax = 9},Max {getMax = 10},Max {getMax = 11}]
+--
+-- >>> pz @(EnumFromTo 1 20 >> Map '(Id, (If (Id `Mod` 3 == 0) "Fizz" "" <> If (Id `Mod` 5 == 0) "Buzz" "")) Id) 123
+-- PresentT [(1,""),(2,""),(3,"Fizz"),(4,""),(5,"Buzz"),(6,"Fizz"),(7,""),(8,""),(9,"Fizz"),(10,"Buzz"),(11,""),(12,"Fizz"),(13,""),(14,""),(15,"FizzBuzz"),(16,""),(17,""),(18,"Fizz"),(19,""),(20,"Buzz")]
+--
+-- >>> pl @(EnumFromTo (Pure SG.Min 9) (Pure _ 13)) ()
+-- Present [Min {getMin = 9},Min {getMin = 10},Min {getMin = 11},Min {getMin = 12},Min {getMin = 13}] (Min {getMin = 9} ... Min {getMin = 13})
+-- PresentT [Min {getMin = 9},Min {getMin = 10},Min {getMin = 11},Min {getMin = 12},Min {getMin = 13}]
+--
+-- >>> pl @(EnumFromTo (Wrap (SG.Min _) 9) (Wrap _ 13)) ()
+-- Present [Min {getMin = 9},Min {getMin = 10},Min {getMin = 11},Min {getMin = 12},Min {getMin = 13}] (Min {getMin = 9} ... Min {getMin = 13})
+-- PresentT [Min {getMin = 9},Min {getMin = 10},Min {getMin = 11},Min {getMin = 12},Min {getMin = 13}]
+--
+data EnumFromTo p q
+
+-- | similar to 'enumFromTo'
+--
+-- >>> pz @(2 ... 5) ()
+-- PresentT [2,3,4,5]
+--
+-- >>> pz @('LT ... 'GT) ()
+-- PresentT [LT,EQ,GT]
+--
+-- >>> pz @('Just (MkDay '(2020, 1, 2)) ... 'Just (MkDay '(2020, 1, 7))) ()
+-- PresentT [2020-01-02,2020-01-03,2020-01-04,2020-01-05,2020-01-06,2020-01-07]
+--
+data p ... q
+infix 4 ...
+
+type EnumFromToT p q = EnumFromTo p q
+
+instance P (EnumFromToT p q) x => P (p ... q) x where
+  type PP (p ... q) x = PP (EnumFromToT p q) x
+  eval _ = eval (Proxy @(EnumFromToT p q))
+
+instance (P p x
+        , P q x
+        , PP p x ~ a
+        , Show a
+        , PP q x ~ a
+        , Enum a
+        ) => P (EnumFromTo p q) x where
+  type PP (EnumFromTo p q) x = [PP p x]
+  eval _ opts z = do
+    let msg0 = "..."
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) -> mkNode opts (PresentT (enumFromTo p q)) (showL opts p <> " " <> msg0 <> " " <> showL opts q) [hh pp, hh qq]
+
+-- | similar to 'enumFromThenTo'
+--
+-- >>> pz @(EnumFromThenTo (ToEnum Day 10) (ToEnum Day 20) (ToEnum Day 70)) ()
+-- PresentT [1858-11-27,1858-12-07,1858-12-17,1858-12-27,1859-01-06,1859-01-16,1859-01-26]
+--
+-- >>> pz @(EnumFromThenTo (ReadP Day "2020-01-12") (ReadP Day "2020-02-12") (ReadP Day "2020-08-12")) ()
+-- PresentT [2020-01-12,2020-02-12,2020-03-14,2020-04-14,2020-05-15,2020-06-15,2020-07-16]
+--
+data EnumFromThenTo p q r
+
+instance (P p x
+        , P q x
+        , P r x
+        , PP p x ~ a
+        , Show a
+        , PP q x ~ a
+        , PP r x ~ a
+        , Enum a
+        ) => P (EnumFromThenTo p q r) x where
+  type PP (EnumFromThenTo p q r) x = [PP p x]
+  eval _ opts z = do
+    let msg0 = "EnumFromThenTo"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        rr <- eval (Proxy @r) opts z
+        pure $ case getValueLR opts (msg0 ++ " r failed") rr [hh pp, hh qq] of
+          Left e -> e
+          Right r ->
+            mkNode opts (PresentT (enumFromThenTo p q r)) (msg0 <> " [" <> showL opts p <> ", " <> showL opts q <> " .. " <> showL opts r <> "]") [hh pp, hh qq, hh rr]
+ src/Predicate/Data/Extra.hs view
@@ -0,0 +1,1053 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     extra promoted functions
+-}
+module Predicate.Data.Extra (
+
+    Pure2
+  , type (<$)
+  , type (<*)
+  , type (*>)
+  , FMapFst
+  , FMapSnd
+  , Sequence
+  , Traverse
+  , Join
+  , type (<|>)
+  , Extract
+  , Duplicate
+
+  , type ($$)
+  , type ($&)
+  , Skip
+  , type (|>)
+  , type (>|)
+  , type (>|>)
+
+  , HeadDef
+  , HeadFail
+  , TailDef
+  , TailFail
+  , LastDef
+  , LastFail
+  , InitDef
+  , InitFail
+
+  , Coerce2
+
+  , ProxyT
+  , ProxyT'
+
+  , Prime
+  , PrimeNext
+  , Luhn
+
+  , Catch
+  , Catch'
+  , Dot
+  , RDot
+  , K
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.List (Uncons, Unsnoc)
+import Predicate.Data.Maybe (JustDef, JustFail)
+import GHC.TypeLits (ErrorMessage((:$$:),(:<>:)))
+import qualified GHC.TypeLits as GL
+import Data.Proxy
+import Control.Applicative
+import Control.Monad (join)
+import Data.Kind (Type)
+import Control.Comonad
+import Data.Coerce
+import Control.Lens hiding (iall)
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> import qualified Data.Text as T
+-- >>> import qualified Data.Sequence as Seq
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.Functor.Identity
+-- >>> import Data.These
+
+-- | lift pure over a Functor
+--
+-- >>> pz @(Pure2 (Either String)) [1,2,4]
+-- PresentT [Right 1,Right 2,Right 4]
+--
+-- >>> pl @(Pure2 []) (Just 10)
+-- Present Just [10] (Pure2 Just [10] | Just 10)
+-- PresentT (Just [10])
+--
+-- >>> pl @(Pure2 SG.Sum) (Just 20)
+-- Present Just (Sum {getSum = 20}) (Pure2 Just (Sum {getSum = 20}) | Just 20)
+-- PresentT (Just (Sum {getSum = 20}))
+--
+data Pure2 (t :: Type -> Type)
+
+instance (Show (f (t a))
+        , Show (f a)
+        , Applicative t
+        , Functor f
+        ) => P (Pure2 t) (f a) where
+  type PP (Pure2 t) (f a) = f (t a)
+  eval _ opts fa =
+    let msg0 = "Pure2"
+        b = fmap pure fa
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b fa) []
+
+-- | similar to 'Control.Applicative.<$'
+--
+-- >>> pz @(Fst Id <$ Snd Id) ("abc",Just 20)
+-- PresentT (Just "abc")
+--
+-- >>> pl @(Fst Id <$ Snd Id) (4,These "xxx" 'a')
+-- Present These "xxx" 4 ((<$) 4)
+-- PresentT (These "xxx" 4)
+--
+-- >>> pl @(Fst Id <$ Snd Id) (4,This 'a')
+-- Present This 'a' ((<$) 4)
+-- PresentT (This 'a')
+--
+-- >>> pl @(Fst Id <$ Snd Id) (4,Just 'a')
+-- Present Just 4 ((<$) 4)
+-- PresentT (Just 4)
+--
+-- >>> pl @(Fst Id <$ Snd Id) (4,Nothing @Int)
+-- Present Nothing ((<$) 4)
+-- PresentT Nothing
+--
+-- >>> pl @('True <$ Id) [1..4]
+-- Present [True,True,True,True] ((<$) True)
+-- PresentT [True,True,True,True]
+--
+-- >>> import Data.Functor.Compose
+-- >>> pl @(Char1 "ab" <$ Id) (Compose $ Just [1..4])
+-- Present Compose (Just "aaaa") ((<$) 'a')
+-- PresentT (Compose (Just "aaaa"))
+--
+-- >>> pl @(Snd Id <$ Fst Id) (Just 10,'x')
+-- Present Just 'x' ((<$) 'x')
+-- PresentT (Just 'x')
+--
+data p <$ q
+infixl 4 <$
+
+instance (P p x
+        , P q x
+        , Show (PP p x)
+        , Functor t
+        , PP q x ~ t c
+        , ApplyConstT (PP q x) (PP p x) ~ t (PP p x)
+        ) => P (p <$ q) x where
+  type PP (p <$ q) x = ApplyConstT (PP q x) (PP p x)
+  eval _ opts x = do
+    let msg0 = "(<$)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = p <$ q
+        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p) [hh pp, hh qq]
+
+-- | similar to Applicative 'Control.Applicative.<*'
+--
+-- >>> pl @(Fst Id <* Snd Id) (Just 4,Just 'a')
+-- Present Just 4 ((<*) Just 4 | p=Just 4 | q=Just 'a')
+-- PresentT (Just 4)
+--
+-- >>> pz @(Fst Id <* Snd Id) (Just "abc",Just 20)
+-- PresentT (Just "abc")
+--
+data p <* q
+infixl 4 <*
+
+type ArrowRT p q = q <* p
+
+-- | similar to Applicative 'Control.Applicative.*>'
+--
+-- >>> pl @(Fst Id *> Snd Id) (Just 4,Just 'a')
+-- Present Just 'a' ((<*) Just 'a' | p=Just 'a' | q=Just 4)
+-- PresentT (Just 'a')
+--
+data p *> q
+infixl 4 *>
+
+instance P (ArrowRT p q) x => P (p *> q) x where
+  type PP (p *> q) x = PP (ArrowRT p q) x
+  eval _ = eval (Proxy @(ArrowRT p q))
+
+instance (Show (t c)
+        , P p x
+        , P q x
+        , Show (t b)
+        , Applicative t
+        , t b ~ PP p x
+        , PP q x ~ t c
+        ) => P (p <* q) x where
+  type PP (p <* q) x = PP p x
+  eval _ opts x = do
+    let msg0 = "(<*)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = p <* q
+        in mkNode opts (PresentT d) (show01' opts msg0 p "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | similar to 'Control.Applicative.<|>'
+--
+-- >>> pz @(Fst Id <|> Snd Id) (Nothing,Just 20)
+-- PresentT (Just 20)
+--
+-- >>> pz @(Fst Id <|> Snd Id) (Just 10,Just 20)
+-- PresentT (Just 10)
+--
+-- >>> pz @(Fst Id <|> Snd Id) (Nothing,Nothing)
+-- PresentT Nothing
+--
+-- >>> pl @(Fst Id <|> Snd Id) (Just "cdef",Just "ab")
+-- Present Just "cdef" ((<|>) Just "cdef" | p=Just "cdef" | q=Just "ab")
+-- PresentT (Just "cdef")
+--
+-- >>> pl @(Fst Id <|> Snd Id) ("cdef","ab"::String)
+-- Present "cdefab" ((<|>) "cdefab" | p="cdef" | q="ab")
+-- PresentT "cdefab"
+--
+data p <|> q
+infixl 3 <|>
+
+instance (P p x
+        , P q x
+        , Show (t b)
+        , Alternative t
+        , t b ~ PP p x
+        , PP q x ~ t b
+        ) => P (p <|> q) x where
+  type PP (p <|> q) x = PP p x
+  eval _ opts x = do
+    let msg0 = "(<|>)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = p <|> q
+        in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+
+-- | similar to 'Control.Comonad.extract'
+--
+-- >>> pz @Extract (Nothing,Just 20)
+-- PresentT (Just 20)
+--
+-- >>> pz @Extract (Identity 20)
+-- PresentT 20
+--
+-- >>> pl @Extract (10,"hello")
+-- Present "hello" (Extract "hello" | (10,"hello"))
+-- PresentT "hello"
+--
+data Extract
+instance (Show (t a)
+        , Show a
+        , Comonad t
+        ) => P Extract (t a) where
+  type PP Extract (t a) = a
+  eval _ opts ta =
+    let msg0 = "Extract"
+        d = extract ta
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d ta) []
+
+-- | similar to 'Control.Comonad.duplicate'
+--
+-- >>> pz @Duplicate (20,"abc")
+-- PresentT (20,(20,"abc"))
+--
+data Duplicate
+
+instance (Show (t a)
+        , Show (t (t a))
+        , Comonad t
+        ) => P Duplicate (t a) where
+  type PP Duplicate (t a) = t (t a)
+  eval _ opts ta =
+    let msg0 = "Duplicate"
+        d = duplicate ta
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d ta) []
+
+-- | similar to 'Control.Monad.join'
+--
+-- >>> pz @Join  (Just (Just 20))
+-- PresentT (Just 20)
+--
+-- >>> pz @Join  ["ab","cd","","ef"]
+-- PresentT "abcdef"
+--
+data Join
+
+instance (Show (t (t a))
+        , Show (t a)
+        , Monad t
+        ) => P Join (t (t a)) where
+  type PP Join (t (t a)) = t a
+  eval _ opts tta =
+    let msg0 = "Join"
+        d = join tta
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d tta) []
+
+-- | function application for expressions: similar to 'GHC.Base.$'
+--
+-- >>> :m + Text.Show.Functions
+-- >>> pz @(Fst Id $$ Snd Id) ((*16),4)
+-- PresentT 64
+--
+-- >>> pz @(Id $$ "def") ("abc"<>)
+-- PresentT "abcdef"
+--
+data p $$ q
+infixl 0 $$
+
+instance (P p x
+        , P q x
+        , PP p x ~ (a -> b)
+        , FnT (PP p x) ~ b
+        , PP q x ~ a
+        , Show a
+        , Show b
+        ) => P (p $$ q) x where
+  type PP (p $$ q) x = FnT (PP p x)
+  eval _ opts x = do
+    let msg0 = "($$)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq)  ->
+        let d = p q
+        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
+
+-- reify this so we can combine (type synonyms dont work as well)
+
+-- | flipped function application for expressions: similar to 'Control.Lens.&'
+--
+-- >>> :m + Text.Show.Functions
+-- >>> pz @(Snd Id $& Fst Id) ((*16),4)
+-- PresentT 64
+--
+-- >>> pz @("def" $& Id) ("abc"<>)
+-- PresentT "abcdef"
+--
+data q $& p -- flips the args eg a & b & (,) = (b,a)
+infixr 1 $&
+
+instance (P p x
+        , P q x
+        , PP p x ~ (a -> b)
+        , FnT (PP p x) ~ b
+        , PP q x ~ a
+        , Show a
+        , Show b
+        ) => P (q $& p) x where
+  type PP (q $& p) x = FnT (PP p x)
+  eval _ opts x = do
+    let msg0 = "($&)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq)  ->
+        let d = p q
+        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
+
+type family FnT ab :: Type where
+  FnT (a -> b) = b
+  FnT ab = GL.TypeError (
+      'GL.Text "FnT: expected Type -> Type but found a simple Type?"
+      ':$$: 'GL.Text "ab = "
+      ':<>: 'GL.ShowType ab)
+
+-- | similar to 'sequenceA'
+--
+-- >>> pz @Sequence [Just 10, Just 20, Just 30]
+-- PresentT (Just [10,20,30])
+--
+-- >>> pz @Sequence [Just 10, Just 20, Just 30, Nothing, Just 40]
+-- PresentT Nothing
+--
+data Sequence
+
+instance (Show (f (t a))
+        , Show (t (f a))
+        , Traversable t
+        , Applicative f
+        ) => P Sequence (t (f a)) where
+  type PP Sequence (t (f a)) = f (t a)
+  eval _ opts tfa =
+     let msg = "Sequence"
+         d = sequenceA tfa
+     in pure $ mkNode opts (PresentT d) (msg <> " " <> showL opts d <> showVerbose opts " | " tfa) []
+
+-- | like 'traverse'
+--
+-- >>> pl @(Traverse (If (Gt 3) (Pure Maybe Id) (EmptyT Maybe Id)) Id) [1..5]
+-- Present Nothing ((>>) Nothing | {Sequence Nothing | [Nothing,Nothing,Nothing,Just 4,Just 5]})
+-- PresentT Nothing
+--
+-- >>> pl @(Traverse (MaybeBool (Le 3) Id) Id) [1..5]
+-- Present Nothing ((>>) Nothing | {Sequence Nothing | [Just 1,Just 2,Just 3,Nothing,Nothing]})
+-- PresentT Nothing
+--
+-- >>> pl @(Traverse (If (Gt 0) (Pure Maybe Id) (EmptyT Maybe Id)) Id) [1..5]
+-- Present Just [1,2,3,4,5] ((>>) Just [1,2,3,4,5] | {Sequence Just [1,2,3,4,5] | [Just 1,Just 2,Just 3,Just 4,Just 5]})
+-- PresentT (Just [1,2,3,4,5])
+--
+-- >>> pl @(Traverse (If (Gt 0) (Pure Maybe Id) (MkNothing _)) Id) [1..5]
+-- Present Just [1,2,3,4,5] ((>>) Just [1,2,3,4,5] | {Sequence Just [1,2,3,4,5] | [Just 1,Just 2,Just 3,Just 4,Just 5]})
+-- PresentT (Just [1,2,3,4,5])
+--
+-- >>> pl @(Traverse (MaybeBool (Id >= 0) Id) Id) [1..5]
+-- Present Just [1,2,3,4,5] ((>>) Just [1,2,3,4,5] | {Sequence Just [1,2,3,4,5] | [Just 1,Just 2,Just 3,Just 4,Just 5]})
+-- PresentT (Just [1,2,3,4,5])
+--
+-- >>> pl @(Traverse (MaybeBool (Id <= 3) Id) Id) [1..5]
+-- Present Nothing ((>>) Nothing | {Sequence Nothing | [Just 1,Just 2,Just 3,Nothing,Nothing]})
+-- PresentT Nothing
+--
+data Traverse p q
+type TraverseT p q = Map p q >> Sequence
+
+instance P (TraverseT p q) x => P (Traverse p q) x where
+  type PP (Traverse p q) x = PP (TraverseT p q) x
+  eval _ = eval (Proxy @(TraverseT p q))
+
+-- | similar to fmap fst
+--
+-- >>> pz @FMapFst (Just (13,"Asf"))
+-- PresentT (Just 13)
+--
+-- >>> pl @FMapFst (Just (1,'x'))
+-- Present Just 1 (FMapFst)
+-- PresentT (Just 1)
+--
+-- >>> pl @FMapFst [(1,'x'), (2,'y'), (3,'z')]
+-- Present [1,2,3] (FMapFst)
+-- PresentT [1,2,3]
+--
+
+-- to make this work we grab the fst or snd out of the Maybe so it is a head or not/ is a tail or not etc!
+-- we still have access to the whole original list so we dont lose anything!
+data FMapFst
+
+instance Functor f => P FMapFst (f (a,x)) where
+  type PP FMapFst (f (a,x)) = f a
+  eval _ opts mb = pure $ mkNode opts (PresentT (fst <$> mb)) "FMapFst" []
+
+-- | similar to fmap snd
+--
+-- >>> pz @FMapSnd (Just ("asf",13))
+-- PresentT (Just 13)
+--
+-- >>> pl @FMapSnd (Just (1,'x'))
+-- Present Just 'x' (FMapSnd)
+-- PresentT (Just 'x')
+--
+-- >>> pl @FMapSnd (Nothing @(Char,Int))
+-- Present Nothing (FMapSnd)
+-- PresentT Nothing
+--
+-- >>> pl @FMapSnd (Right (1,'x'))
+-- Present Right 'x' (FMapSnd)
+-- PresentT (Right 'x')
+--
+-- >>> pl @FMapSnd (Left @_ @(Int,Double) "x")
+-- Present Left "x" (FMapSnd)
+-- PresentT (Left "x")
+--
+
+data FMapSnd
+
+instance Functor f => P FMapSnd (f (x,a)) where
+  type PP FMapSnd (f (x,a)) = f a
+  eval _ opts mb = pure $ mkNode opts (PresentT (snd <$> mb)) "FMapSnd" []
+
+-- | just run the effect ignoring the result passing the original value through
+-- for example for use with Stdout so it doesnt interfere with the \'a\' on the rhs unless there is an failure
+data Skip p
+
+instance ( Show (PP p a)
+         , P p a
+         ) => P (Skip p) a where
+  type PP (Skip p) a = a
+  eval _ opts a = do
+    let msg0 = "Skip"
+    pp <- eval (Proxy @p) opts a
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts p) [hh pp]
+
+-- | run \'p\' for the effect and then run \'q\' using that original value
+data p |> q
+type SkipLT p q = Skip p >> q
+infixr 1 |>
+
+instance P (SkipLT p q) x => P (p |> q) x where
+  type PP (p |> q) x = PP (SkipLT p q) x
+  eval _ = eval (Proxy @(SkipLT p q))
+
+-- | run run \'p\' and then \'q\' for the effect but using the result from \'p\'
+data p >| q
+type SkipRT p q = p >> Skip q
+infixr 1 >|
+
+instance P (SkipRT p q) x => P (p >| q) x where
+  type PP (p >| q) x = PP (SkipRT p q) x
+  eval _ = eval (Proxy @(SkipRT p q))
+
+-- | run both \'p\' and \'q\' for their effects but ignoring the results
+data p >|> q
+type SkipBothT p q = Skip p >> Skip q
+infixr 1 >|>
+
+instance P (SkipBothT p q) x => P (p >|> q) x where
+  type PP (p >|> q) x = PP (SkipBothT p q) x
+  eval _ = eval (Proxy @(SkipBothT p q))
+
+-- | takes the head of a list-like object or uses the given default value
+--
+-- see 'ConsT' for other supported types eg 'Seq.Seq'
+--
+-- >>> pz @(HeadDef 444 Id) []
+-- PresentT 444
+--
+-- >>> pz @(HeadDef 444 Id) [1..5]
+-- PresentT 1
+--
+-- >>> pz @(HeadDef 444 Id) [1..5]
+-- PresentT 1
+--
+-- >>> pz @(HeadDef (Char1 "w") Id) (Seq.fromList "abcdef")
+-- PresentT 'a'
+--
+-- >>> pz @(HeadDef (Char1 "w") Id) Seq.empty
+-- PresentT 'w'
+--
+-- >>> pz @(HeadDef (MEmptyT _) Id) ([] :: [SG.Sum Int])
+-- PresentT (Sum {getSum = 0})
+--
+-- >>> pz @(HeadDef (MEmptyT String) '["abc","def","asdfadf"]) ()
+-- PresentT "abc"
+--
+-- >>> pz @(HeadDef (MEmptyT _) (Snd Id)) (123,["abc","def","asdfadf"])
+-- PresentT "abc"
+--
+-- >>> pz @(HeadDef (MEmptyT _) (Snd Id)) (123,[])
+-- PresentT ()
+--
+-- >>> pl @(HeadDef 9 (Fst Id)) ([],True)
+-- Present 9 (JustDef Nothing)
+-- PresentT 9
+--
+-- >>> pl @(HeadDef 9 (Fst Id)) ([1..5],True)
+-- Present 1 (JustDef Just)
+-- PresentT 1
+--
+-- >>> pl @(HeadDef 3 (Fst Id)) ([10..15],True)
+-- Present 10 (JustDef Just)
+-- PresentT 10
+--
+-- >>> pl @(HeadDef 12 (Fst Id) >> Le 6) ([],True)
+-- False ((>>) False | {12 <= 6})
+-- FalseT
+--
+-- >>> pl @(HeadDef 1 (Fst Id) >> Le 6) ([],True)
+-- True ((>>) True | {1 <= 6})
+-- TrueT
+--
+-- >>> pl @(HeadDef 10 (Fst Id) >> Le 6) ([],True)
+-- False ((>>) False | {10 <= 6})
+-- FalseT
+--
+-- >>> pl @(HeadDef (MEmptyT _) Id) (map (:[]) ([] :: [Int]))
+-- Present [] (JustDef Nothing)
+-- PresentT []
+--
+-- >>> pl @(HeadDef (MEmptyT _) Id) (map (:[]) ([10..14] :: [Int]))
+-- Present [10] (JustDef Just)
+-- PresentT [10]
+--
+-- >>> pl @(HeadDef (Fst Id) (Snd Id)) (99,[10..14])
+-- Present 10 (JustDef Just)
+-- PresentT 10
+--
+-- >>> pl @(HeadDef (Fst Id) (Snd Id)) (99,[] :: [Int])
+-- Present 99 (JustDef Nothing)
+-- PresentT 99
+--
+-- >>> pl @(HeadDef 43 (Snd Id)) (99,[] :: [Int])
+-- Present 43 (JustDef Nothing)
+-- PresentT 43
+--
+data HeadDef p q
+type HeadDefT p q = JustDef p (q >> Uncons >> FMapFst)
+
+instance P (HeadDefT p q) x => P (HeadDef p q) x where
+  type PP (HeadDef p q) x = PP (HeadDefT p q) x
+  eval _ = eval (Proxy @(HeadDefT p q))
+
+
+-- | takes the head of a list or fails with the given message
+--
+-- see 'ConsT' for other supported types eg 'Seq.Seq'
+--
+-- >>> pz @(HeadFail "dude" Id) ["abc","def","asdfadf"]
+-- PresentT "abc"
+--
+-- >>> pz @(HeadFail "empty list" Id) []
+-- FailT "empty list"
+--
+-- >>> pl @(HeadFail "zz" (Fst Id) >> Le 6) ([],True)
+-- Error zz ((>>) lhs failed)
+-- FailT "zz"
+--
+-- >>> pl @((HeadFail "failed1" (Fst Id) >> Le 6) || 'False) ([],True)
+-- Error failed1 (||)
+-- FailT "failed1"
+--
+-- >>> pl @((Fst Id >> HeadFail "failed2" Id >> Le (6 -% 1)) || 'False) ([-9],True)
+-- True (True || False)
+-- TrueT
+--
+-- >>> pl @(HeadFail "Asdf" Id) ([] :: [()]) -- breaks otherwise
+-- Error Asdf (JustFail Nothing)
+-- FailT "Asdf"
+--
+-- >>> pl @(HeadFail (PrintF "msg=%s def" (Fst Id)) (Snd Id)) ("Abc" :: String,[]::[Int])
+-- Error msg=Abc def (JustFail Nothing)
+-- FailT "msg=Abc def"
+--
+
+data HeadFail msg q
+type HeadFailT msg q = JustFail msg (q >> Uncons >> FMapFst)
+
+instance P (HeadFailT msg q) x => P (HeadFail msg q) x where
+  type PP (HeadFail msg q) x = PP (HeadFailT msg q) x
+  eval _ = eval (Proxy @(HeadFailT msg q))
+
+-- | takes the tail of a list-like object or uses the given default value
+--
+-- >>> pl @(TailDef '[9,7] (Fst Id)) ([],True)
+-- Present [9,7] (JustDef Nothing)
+-- PresentT [9,7]
+--
+-- >>> pl @(TailDef '[9,7] (Fst Id)) ([1..5],True)
+-- Present [2,3,4,5] (JustDef Just)
+-- PresentT [2,3,4,5]
+--
+-- >>> pl @(TailDef '[3] (Fst Id)) ([10..15],True)
+-- Present [11,12,13,14,15] (JustDef Just)
+-- PresentT [11,12,13,14,15]
+--
+
+data TailDef p q
+type TailDefT p q = JustDef p (q >> Uncons >> FMapSnd)
+
+instance P (TailDefT p q) x => P (TailDef p q) x where
+  type PP (TailDef p q) x = PP (TailDefT p q) x
+  eval _ = eval (Proxy @(TailDefT p q))
+
+
+-- | takes the tail of a list-like object or fails with the given message
+--
+-- >>> pl @(TailFail (PrintT "a=%d b=%s" (Snd Id)) (Fst Id)) ([]::[()],(4::Int,"someval" :: String))
+-- Error a=4 b=someval (JustFail Nothing)
+-- FailT "a=4 b=someval"
+--
+
+data TailFail msg q
+type TailFailT msg q = JustFail msg (q >> Uncons >> FMapSnd)
+
+instance P (TailFailT msg q) x => P (TailFail msg q) x where
+  type PP (TailFail msg q) x = PP (TailFailT msg q) x
+  eval _ = eval (Proxy @(TailFailT msg q))
+
+-- | takes the last value of a list-like object or a default value
+--
+-- >>> pl @(LastDef 9 (Fst Id)) ([],True)
+-- Present 9 (JustDef Nothing)
+-- PresentT 9
+--
+-- >>> pl @(LastDef 9 (Fst Id)) ([1..5],True)
+-- Present 5 (JustDef Just)
+-- PresentT 5
+--
+-- >>> pl @(LastDef 3 (Fst Id)) ([10..15],True)
+-- Present 15 (JustDef Just)
+-- PresentT 15
+--
+-- >>> pl @(LastDef 0 Id) [1..12]
+-- Present 12 (JustDef Just)
+-- PresentT 12
+--
+-- >>> pl @(LastDef 0 Id) []
+-- Present 0 (JustDef Nothing)
+-- PresentT 0
+--
+
+data LastDef p q
+type LastDefT p q = JustDef p (q >> Unsnoc >> FMapSnd)
+
+instance P (LastDefT p q) x => P (LastDef p q) x where
+  type PP (LastDef p q) x = PP (LastDefT p q) x
+  eval _ = eval (Proxy @(LastDefT p q))
+
+-- | takes the init of a list-like object or fails with the given message
+data LastFail msg q
+type LastFailT msg q = JustFail msg (q >> Unsnoc >> FMapSnd)
+
+instance P (LastFailT msg q) x => P (LastFail msg q) x where
+  type PP (LastFail msg q) x = PP (LastFailT msg q) x
+  eval _ = eval (Proxy @(LastFailT msg q))
+
+-- | takes the init of a list-like object or uses the given default value
+--
+-- >>> pl @(InitDef '[9,7] (Fst Id)) ([],True)
+-- Present [9,7] (JustDef Nothing)
+-- PresentT [9,7]
+--
+-- >>> pl @(InitDef '[9,7] (Fst Id)) ([1..5],True)
+-- Present [1,2,3,4] (JustDef Just)
+-- PresentT [1,2,3,4]
+--
+-- >>> pl @(InitDef '[3] (Fst Id)) ([10..15],True)
+-- Present [10,11,12,13,14] (JustDef Just)
+-- PresentT [10,11,12,13,14]
+--
+data InitDef p q
+type InitDefT p q = JustDef p (q >> Unsnoc >> FMapFst)
+
+instance P (InitDefT p q) x => P (InitDef p q) x where
+  type PP (InitDef p q) x = PP (InitDefT p q) x
+  eval _ = eval (Proxy @(InitDefT p q))
+
+-- | takes the init of a list-like object or fails with the given message
+data InitFail msg q
+type InitFailT msg q = JustFail msg (q >> Unsnoc >> FMapFst)
+
+instance P (InitFailT msg q) x => P (InitFail msg q) x where
+  type PP (InitFail msg q) x = PP (InitFailT msg q) x
+  eval _ = eval (Proxy @(InitFailT msg q))
+
+type family ApplyConstT (ta :: Type) (b :: Type) :: Type where
+--type family ApplyConstT ta b where -- less restrictive so allows ('Just Int) Bool through!
+  ApplyConstT (t a) b = t b
+  ApplyConstT ta b = GL.TypeError (
+       'GL.Text "ApplyConstT: (t a) b but found something else"
+       ':$$: 'GL.Text "t a = "
+       ':<>: 'GL.ShowType ta
+       ':$$: 'GL.Text "b = "
+       ':<>: 'GL.ShowType b)
+
+-- | a predicate on prime numbers
+--
+-- >>> pz @(Prime Id) 2
+-- TrueT
+--
+-- >>> pz @(Map '(Id,Prime Id) Id) [0..12]
+-- PresentT [(0,False),(1,False),(2,True),(3,True),(4,False),(5,True),(6,False),(7,True),(8,False),(9,False),(10,False),(11,True),(12,False)]
+--
+data Prime p
+
+instance (PP p x ~ a
+        , P p x
+        , Show a
+        , Integral a
+        ) => P (Prime p) x where
+  type PP (Prime p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Prime"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = p > 1 && isPrime (fromIntegral p)
+        in mkNodeB opts b (msg0 <> showVerbose opts " | " p) [hh pp]
+
+-- | get the next prime number
+--
+-- >>> pz @(PrimeNext Id) 6
+-- PresentT 7
+--
+-- >>> pz @(ScanN 4 (PrimeNext Id) Id) 3
+-- PresentT [3,5,7,11,13]
+--
+data PrimeNext p
+
+instance (PP p x ~ a
+        , P p x
+        , Show a
+        , Integral a
+        ) => P (PrimeNext p) x where
+  type PP (PrimeNext p) x = Int
+  eval _ opts x = do
+    let msg0 = "PrimeNext"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let ret = head $ dropWhile (not . isPrime) [max 0 (fromIntegral p + 1) ..]
+        in mkNode opts (PresentT ret) (msg0 <> showVerbose opts " | " p) [hh pp]
+
+-- | Luhn predicate check on last digit
+--
+-- >>> pz @(Luhn Id) [1,2,3,0]
+-- TrueT
+--
+-- >>> pz @(Luhn Id) [1,2,3,4]
+-- FalseT
+--
+-- >>> pz @(GuardSimple (Luhn Id)) [15,4,3,1,99]
+-- FailT "(Luhn map=[90,2,3,8,6] sum=109 ret=9 | [15,4,3,1,99])"
+--
+-- >>> pl @(Luhn Id) [15,4,3,1,99]
+-- False (Luhn map=[90,2,3,8,6] sum=109 ret=9 | [15,4,3,1,99])
+-- FalseT
+--
+data Luhn p
+
+instance (PP p x ~ [Int]
+        , P p x
+        ) => P (Luhn p) x where
+  type PP (Luhn p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Luhn"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let xs = zipWith (*) (reverse p) (cycle [1,2])
+            ys = map (\w -> if w>=10 then w-9 else w) xs
+            z = sum ys
+            ret = z `mod` 10
+            hhs = [hh pp]
+        in if ret == 0 then mkNodeB opts True (msg0 <> " | " <> showL opts p) hhs
+           else mkNodeB opts False (msg0 <> " map=" <> showL opts ys <> " sum=" <> showL opts z <> " ret=" <> showL opts ret <> showVerbose opts " | " p) hhs
+
+-- | coerce over a functor
+--
+-- >>> pz @(Coerce2 (SG.Sum Integer)) [Identity (-13), Identity 4, Identity 99]
+-- PresentT [Sum {getSum = -13},Sum {getSum = 4},Sum {getSum = 99}]
+--
+-- >>> pz @(Coerce2 (SG.Sum Integer)) (Just (Identity (-13)))
+-- PresentT (Just (Sum {getSum = -13}))
+--
+-- >>> pz @(Coerce2 (SG.Sum Int)) (Nothing @(Identity Int))
+-- PresentT Nothing
+--
+-- >>> pl @(Coerce2 (SG.Sum Int)) (Just (10 :: Int))
+-- Present Just (Sum {getSum = 10}) (Coerce2 Just (Sum {getSum = 10}) | Just 10)
+-- PresentT (Just (Sum {getSum = 10}))
+--
+data Coerce2 (t :: k)
+instance (Show (f a)
+        , Show (f t)
+        , Coercible t a
+        , Functor f
+        ) => P (Coerce2 t) (f a) where
+  type PP (Coerce2 t) (f a) = f t
+  eval _ opts fa =
+    let msg0 = "Coerce2"
+        d = view coerced <$> fa
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d fa) []
+
+data ProxyT' t
+
+instance P (ProxyT' t) x where
+  type PP (ProxyT' t) x = Proxy (PP t x)
+  eval _ opts _ =
+    pure $ mkNode opts (PresentT Proxy) "ProxyT" []
+
+data ProxyT (t :: Type)
+type ProxyTT (t :: Type) = ProxyT' (Hole t)
+
+instance P (ProxyT t) x where
+  type PP (ProxyT t) x = PP (ProxyTT t) x
+  eval _ = eval (Proxy @(ProxyTT t))
+
+
+
+-- more flexible: takes a (String,x) and a proxy so we can still call 'False 'True
+-- now takes the FailT string and x so you can print more detail if you want
+-- need the proxy so we can fail without having to explicitly specify a type
+
+-- | run an expression \'p\' and on failure run \'q\'
+--
+-- >>> pz @(Catch (Succ Id) (Fst Id >> Second (ShowP Id) >> PrintT "%s %s" Id >> 'LT)) GT
+-- PresentT LT
+--
+-- >>> pz @(Len > 1 && Catch (Id !! 3 == 66) 'False) [1,2]
+-- FalseT
+--
+-- >>> pl @(Catch (Resplit "\\d+(" Id) (Snd Id >> MEmptyP)) "123"
+-- Present [] (Catch caught exception[Regex failed to compile])
+-- PresentT []
+--
+-- >>> pl @(Catch (OneP Id) 99) [10,11]
+-- Present 99 (Catch caught exception[OneP 2 elements])
+-- PresentT 99
+--
+-- >>> pl @(Catch (OneP Id) 99) [10]
+-- Present 10 (Catch did not fire)
+-- PresentT 10
+--
+-- >>> pl @(Catch (OneP Id) 'True) [False]  -- cant know that this is FalseT cos is driven by type of the list not the 'True part
+-- Present False (Catch did not fire)
+-- PresentT False
+--
+-- >>> pl @(Catch (OneP Id) 'False) [True,True,False]
+-- False (Catch caught exception[OneP 3 elements])
+-- FalseT
+--
+-- >>> pl @(Catch (OneP Id) 'True) []
+-- True (Catch caught exception[OneP empty])
+-- TrueT
+--
+data Catch p q
+
+-- | run an expression \'p\' and on failure print a custom error \'s\' using the error string and the input value
+--
+-- >>> pz @(Catch' (Succ Id) (Second (ShowP Id) >> PrintT "%s %s" Id)) GT
+-- FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument GT"
+--
+-- >>> pz @(Catch' (Succ Id) (Second (ShowP Id) >> PrintT "%s %s" Id)) LT
+-- PresentT EQ
+--
+-- >>> pl @(Catch' (Failt Int "someval") (PrintT "msg=%s caught(%03d)" Id)) (44 :: Int)
+-- Error msg=someval caught(044) (Catch default condition failed)
+-- FailT "msg=someval caught(044)"
+--
+-- >>> pl @(Catch' (OneP Id) (Second (ShowP Id) >> PrintT "msg=%s caught(%s)" Id)) [10,12,13]
+-- Error msg=OneP 3 elements caught([10,12,13]) (Catch default condition failed)
+-- FailT "msg=OneP 3 elements caught([10,12,13])"
+--
+-- >>> pl @(Catch' (OneP Id) (PrintT "msg=%s caught(%s)" (Second (ShowP Id)))) [10]
+-- Present 10 (Catch did not fire)
+-- PresentT 10
+--
+-- >>> pl @(Catch' (OneP Id) (PrintT "msg=%s err s=%s" (Second (ShowP Id)))) [10,11]
+-- Error msg=OneP 2 elements err s=[10,11] (Catch default condition failed)
+-- FailT "msg=OneP 2 elements err s=[10,11]"
+--
+data Catch' p s
+type CatchT' p s = Catch p (FailCatchT s) -- eg set eg s=PrintF "%d" Id or PrintF "%s" (ShowP Id)
+type FailCatchT s = Fail (Snd Id >> Unproxy) (Fst Id >> s)
+
+instance P (CatchT' p s) x => P (Catch' p s) x where
+  type PP (Catch' p s) x = PP (CatchT' p s) x
+  eval _ = eval (Proxy @(CatchT' p s))
+
+instance (P p x
+        , P q ((String, x)
+        , Proxy (PP p x))
+        , PP p x ~ PP q ((String, x), Proxy (PP p x))
+        ) => P (Catch p q) x where
+  type PP (Catch p q) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Catch"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> do
+         let emsg = e ^?! tBool . _FailT -- extract the failt string a push back into the fail case
+         qq <- eval (Proxy @q) opts ((emsg, x), Proxy @(PP p x))
+         pure $ case getValueLR opts (msg0 <> " default condition failed") qq [hh pp] of
+            Left e1 -> e1
+            Right _ -> mkNode opts (_tBool qq) (msg0 <> " caught exception[" <> emsg <> "]") [hh pp, hh qq]
+      Right _ -> pure $ mkNode opts (_tBool pp) (msg0 <> " did not fire") [hh pp]
+
+
+
+-- | compose simple functions
+--
+-- >>> pl @(Dot '[Thd,Snd,Fst] Id) ((1,(2,9,10)),(3,4))
+-- Present 10 (Thd 10 | (2,9,10))
+-- PresentT 10
+--
+data Dot (ps :: [Type -> Type]) (q :: Type)
+instance (P (DotExpandT ps q) a) => P (Dot ps q) a where
+  type PP (Dot ps q) a = PP (DotExpandT ps q) a
+  eval _ = eval (Proxy @(DotExpandT ps q))
+
+type family DotExpandT (ps :: [Type -> Type]) (q :: Type) :: Type where
+  DotExpandT '[] _ = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
+  DotExpandT '[p] q = p $ q
+  DotExpandT (p ': p1 ': ps) q = p $ DotExpandT (p1 ': ps) q
+
+-- | reversed version of 'Dot'
+--
+-- >>> pl @(RDot '[Fst,Snd,Thd] Id) ((1,(2,9,10)),(3,4))
+-- Present 10 (Thd 10 | (2,9,10))
+-- PresentT 10
+--
+-- >>> pl @(RDot '[Fst,Snd] Id) (('a',2),(True,"zy"))
+-- Present 2 (Snd 2 | ('a',2))
+-- PresentT 2
+--
+data RDot (ps :: [Type -> Type]) (q :: Type)
+instance P (RDotExpandT ps q) a => P (RDot ps q) a where
+  type PP (RDot ps q) a = PP (RDotExpandT ps q) a
+  eval _ = eval (Proxy @(RDotExpandT ps q))
+
+type family RDotExpandT (ps :: [Type -> Type]) (q :: Type) :: Type where
+  RDotExpandT '[] _ = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
+  RDotExpandT '[p] q = p $ q
+  RDotExpandT (p ': p1 ': ps) q = RDotExpandT (p1 ': ps) (p $ q)
+
+-- | creates a constant expression ignoring the second argument
+--
+-- >>> pl @(RDot '[Fst,Snd,Thd,K "xxx"] Id) ((1,(2,9,10)),(3,4))
+-- Present "xxx" (K '"xxx")
+-- PresentT "xxx"
+--
+-- >>> pl @(RDot '[Fst,Snd,Thd,K '("abc",Id)] Id) ((1,(2,9,10)),(3,4))
+-- Present ("abc",((1,(2,9,10)),(3,4))) (K '("abc",((1,(2,9,10)),(3,4))))
+-- PresentT ("abc",((1,(2,9,10)),(3,4)))
+--
+-- >>> pl @(Thd $ Snd $ Fst $ K Id "dud") ((1,("W",9,'a')),(3,4))
+-- Present 'a' (Thd 'a' | ("W",9,'a'))
+-- PresentT 'a'
+--
+-- >>> pl @((Thd $ Snd $ Fst $ K Id "dud") >> Pred Id) ((1,("W",9,'a')),(3,4))
+-- Present '`' ((>>) '`' | {Pred '`' | 'a'})
+-- PresentT '`'
+--
+data K (p :: k) (q :: k1)
+instance P p a => P (K p q) a where
+  type PP (K p q) a = PP p a
+  eval _ = eval (Proxy @(MsgI "K " p))
+
+-- k or prt has access to (Int,a) where Int is the current guard position: hence need to use PrintT
+-- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out)
+
+
+
+ src/Predicate/Data/Foldable.hs view
@@ -0,0 +1,531 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{-# LANGUAGE ViewPatterns #-}
+{- |
+     promoted foldable functions
+-}
+module Predicate.Data.Foldable (
+    Concat
+  , ConcatMap
+  , Cycle
+  , FoldMap
+
+  , ToListExt
+  , FromList
+  , FromListExt
+
+  , ToList
+  , ToList'
+
+  , IToList
+  , IToList'
+
+  , ToNEList
+
+  , Null
+  , Null'
+  , IsEmpty
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Monoid (MConcat)
+import Control.Lens hiding (iall)
+import Data.Proxy
+import Data.Typeable
+import Data.Kind (Type)
+import Data.Foldable
+import qualified Data.List.NonEmpty as N
+import Data.List.NonEmpty (NonEmpty(..))
+import qualified GHC.Exts as GE
+
+-- $setup
+-- >>> import Predicate.Prelude
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XAllowAmbiguousTypes
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> :set -XFlexibleContexts
+-- >>> import qualified Data.Map.Strict as M
+-- >>> import qualified Data.Set as Set
+-- >>> import qualified Data.Text as T
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.These
+-- >>> import Data.Time
+
+-- | create a 'NonEmpty' list from a 'Foldable'
+--
+-- >>> pz @ToNEList []
+-- FailT "empty list"
+--
+-- >>> pz @ToNEList [1,2,3,4,5]
+-- PresentT (1 :| [2,3,4,5])
+--
+data ToNEList
+instance (Show (t a)
+        , Foldable t
+        ) => P ToNEList (t a) where
+  type PP ToNEList (t a) = NonEmpty a
+  eval _ opts as =
+    let msg0 = "ToNEList"
+    in pure $ case toList as of
+         [] -> mkNode opts (FailT "empty list") msg0 []
+         x:xs -> mkNode opts (PresentT (x N.:| xs)) (msg0 <> showVerbose opts " " as) []
+
+
+-- cant directly create a singleton type using '[] since the type of '[] is unknown. instead use 'Singleton' or 'EmptyT'
+
+-- | similar to 'null' using 'AsEmpty'
+--
+-- >>> pz @IsEmpty [1,2,3,4]
+-- FalseT
+--
+-- >>> pz @IsEmpty []
+-- TrueT
+--
+-- >>> pz @IsEmpty LT
+-- FalseT
+--
+-- >>> pz @IsEmpty EQ
+-- TrueT
+--
+-- >>> pl @IsEmpty ("failed11" :: T.Text)
+-- False (IsEmpty | "failed11")
+-- FalseT
+--
+-- >>> pl @IsEmpty ("" :: T.Text)
+-- True (IsEmpty | "")
+-- TrueT
+--
+data IsEmpty
+
+instance ( Show as
+         , AsEmpty as
+         ) => P IsEmpty as where
+  type PP IsEmpty as = Bool
+  eval _ opts as =
+    let b = has _Empty as
+    in pure $ mkNodeB opts b ("IsEmpty" <> showVerbose opts " | " as) []
+
+
+-- | similar to 'Control.Lens.itoList'
+--
+-- >>> pz @(IToList _ Id) ("aBc" :: String)
+-- PresentT [(0,'a'),(1,'B'),(2,'c')]
+--
+-- >>> pl @(IToList _ Id) ("abcd" :: String)
+-- Present [(0,'a'),(1,'b'),(2,'c'),(3,'d')] (IToList(Int) [(0,'a'),(1,'b'),(2,'c'),(3,'d')] | "abcd")
+-- PresentT [(0,'a'),(1,'b'),(2,'c'),(3,'d')]
+--
+-- >>> pl @(IToList _ Id) (M.fromList $ itoList ("abcd" :: String))
+-- Present [(0,'a'),(1,'b'),(2,'c'),(3,'d')] (IToList(Int) [(0,'a'),(1,'b'),(2,'c'),(3,'d')] | fromList [(0,'a'),(1,'b'),(2,'c'),(3,'d')])
+-- PresentT [(0,'a'),(1,'b'),(2,'c'),(3,'d')]
+--
+-- >>> pl @(IToList _ Id) [9,2,7,4]
+-- Present [(0,9),(1,2),(2,7),(3,4)] (IToList(Int) [(0,9),(1,2),(2,7),(3,4)] | [9,2,7,4])
+-- PresentT [(0,9),(1,2),(2,7),(3,4)]
+--
+-- >>> pl @(IToList _ Id) (M.fromList (zip ['a'..] [9,2,7,4]))
+-- Present [('a',9),('b',2),('c',7),('d',4)] (IToList(Char) [('a',9),('b',2),('c',7),('d',4)] | fromList [('a',9),('b',2),('c',7),('d',4)])
+-- PresentT [('a',9),('b',2),('c',7),('d',4)]
+--
+-- >>> pl @(IToList _ Id) (Just 234)
+-- Present [((),234)] (IToList(()) [((),234)] | Just 234)
+-- PresentT [((),234)]
+--
+-- >>> pl @(IToList _ Id) (Nothing @Double)
+-- Present [] (IToList(()) [] | Nothing)
+-- PresentT []
+--
+-- >>> pl @(IToList _ Id) [1..5]
+-- Present [(0,1),(1,2),(2,3),(3,4),(4,5)] (IToList(Int) [(0,1),(1,2),(2,3),(3,4),(4,5)] | [1,2,3,4,5])
+-- PresentT [(0,1),(1,2),(2,3),(3,4),(4,5)]
+--
+-- >>> pl @(IToList _ Id) ['a','b','c']
+-- Present [(0,'a'),(1,'b'),(2,'c')] (IToList(Int) [(0,'a'),(1,'b'),(2,'c')] | "abc")
+-- PresentT [(0,'a'),(1,'b'),(2,'c')]
+--
+
+data IToList' t p
+
+instance (Show x
+        , P p x
+        , Typeable (PP t (PP p x))
+        , Show (PP t (PP p x))
+        , FoldableWithIndex (PP t (PP p x)) f
+        , PP p x ~ f a
+        , Show a
+        ) => P (IToList' t p) x where
+  type PP (IToList' t p) x = [(PP t (PP p x), ExtractAFromTA (PP p x))]
+  eval _ opts x = do
+    let msg0 = "IToList"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = itoList p
+            t = showT @(PP t (PP p x))
+        in mkNode opts (PresentT b) (msg0 <> "(" <> t <> ") " <> showL opts b <> showVerbose opts " | " x) [hh pp]
+
+data IToList (t :: Type) p
+type IToListT (t :: Type) p = IToList' (Hole t) p
+
+instance P (IToListT t p) x => P (IToList t p) x where
+  type PP (IToList t p) x = PP (IToListT t p) x
+  eval _ = eval (Proxy @(IToListT t p))
+
+-- | invokes 'GE.toList'
+--
+-- >>> pz @ToListExt (M.fromList [(1,'x'),(4,'y')])
+-- PresentT [(1,'x'),(4,'y')]
+--
+-- >>> pz @ToListExt (T.pack "abc")
+-- PresentT "abc"
+--
+data ToListExt
+
+instance (Show l
+        , GE.IsList l
+        , Show (GE.Item l)
+        ) => P ToListExt l where
+  type PP ToListExt l = [GE.Item l]
+  eval _ opts as =
+    let msg0 = "ToListExt"
+        z = GE.toList as
+    in pure $ mkNode opts (PresentT z) (show01 opts msg0 z as) []
+
+-- | invokes 'GE.fromList'
+--
+-- >>> run @('OMsg "Fred" ':# 'OLite ':# 'OColorOff) @(FromList (Set.Set Int) << '[2,1,5,5,2,5,2]) ()
+-- Fred >>> Present fromList [1,2,5] ((>>) fromList [1,2,5] | {FromList fromList [1,2,5]})
+-- PresentT (fromList [1,2,5])
+--
+-- >>> pl @(FromList (M.Map _ _) >> I !! Char1 "y") [('x',True),('y',False)]
+-- Present False ((>>) False | {IxL('y') False | p=fromList [('x',True),('y',False)] | q='y'})
+-- PresentT False
+--
+-- >>> pl @(FromList (M.Map _ _) >> Id !! Char1 "z") [('x',True),('y',False)]
+-- Error (!!) index not found (fromList [('x',True),('y',False)] (>>) rhs failed)
+-- FailT "(!!) index not found"
+--
+
+data FromList (t :: Type) -- doesnt work with OverloadedLists unless you cast to [a] explicitly
+
+instance (a ~ GE.Item t
+        , Show t
+        , GE.IsList t
+        , [a] ~ x
+        ) => P (FromList t) x where
+  type PP (FromList t) x = t
+  eval _ opts as =
+    let msg0 = "FromList"
+        z = GE.fromList (as :: [GE.Item t]) :: t
+    in pure $ mkNode opts (PresentT z) (msg0 <> " " <> showL opts z) []
+
+-- | invokes 'GE.fromList'
+--
+-- requires the OverloadedLists extension
+--
+-- >>> :set -XOverloadedLists
+-- >>> pz @(FromListExt (M.Map _ _)) [(4,"x"),(5,"dd")]
+-- PresentT (fromList [(4,"x"),(5,"dd")])
+--
+data FromListExt (t :: Type)
+-- l ~ l' is key
+instance (Show l
+        , GE.IsList l
+        , l ~ l'
+        ) => P (FromListExt l') l where
+  type PP (FromListExt l') l = l'
+  eval _ opts as =
+    let msg0 = "FromListExt"
+        z = GE.fromList (GE.toList @l as)
+    in pure $ mkNode opts (PresentT z) (msg0 <> " " <> showL opts z) []
+
+-- | similar to 'concat'
+--
+-- >>> pz @(Concat Id) ["abc","D","eF","","G"]
+-- PresentT "abcDeFG"
+--
+-- >>> pz @(Concat (Snd Id)) ('x',["abc","D","eF","","G"])
+-- PresentT "abcDeFG"
+--
+data Concat p
+
+instance (Show a
+        , Show (t [a])
+        , PP p x ~ t [a]
+        , P p x
+        , Foldable t
+        ) => P (Concat p) x where
+  type PP (Concat p) x = ExtractAFromTA (PP p x)
+  eval _ opts x = do
+    let msg0 = "Concat"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = concat p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+-- | similar to 'concatMap'
+data ConcatMap p q
+type ConcatMapT p q = Concat (Map p q)
+
+instance P (ConcatMapT p q) x => P (ConcatMap p q) x where
+  type PP (ConcatMap p q) x = PP (ConcatMapT p q) x
+  eval _ = eval (Proxy @(ConcatMapT p q))
+
+
+-- | similar to 'cycle' but for a fixed number \'n\'
+--
+-- >>> pz @(Cycle 5 Id) [1,2]
+-- PresentT [1,2,1,2,1]
+--
+data Cycle n p
+
+instance (Show a
+        , Show (t a)
+        , PP p x ~ t a
+        , P p x
+        , Integral (PP n x)
+        , P n x
+        , Foldable t
+        ) => P (Cycle n p) x where
+  type PP (Cycle n p) x = [ExtractAFromTA (PP p x)]
+  eval _ opts x = do
+    let msg0 = "Cycle"
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (fromIntegral -> n,p,nn,pp) ->
+        let hhs = [hh nn, hh pp]
+        in case chkSize opts msg0 p hhs of
+            Left e ->  e
+            Right () ->
+              let msg1 = msg0 <> "(" <> show n <> ")"
+                  d = take n (cycle (toList p))
+              in mkNode opts (PresentT d) (show01 opts msg1 d p) hhs
+
+
+-- | similar to 'toList'
+--
+-- >>> pz @ToList "aBc"
+-- PresentT "aBc"
+--
+-- >>> pz @ToList (Just 14)
+-- PresentT [14]
+--
+-- >>> pz @ToList Nothing
+-- PresentT []
+--
+-- >>> pz @ToList (Left "xx")
+-- PresentT []
+--
+-- >>> pz @ToList (These 12 "xx")
+-- PresentT ["xx"]
+--
+-- >>> pl @ToList (M.fromList $ zip [0..] "abcd")
+-- Present "abcd" (ToList fromList [(0,'a'),(1,'b'),(2,'c'),(3,'d')])
+-- PresentT "abcd"
+--
+-- >>> pl @ToList (Just 123)
+-- Present [123] (ToList Just 123)
+-- PresentT [123]
+--
+-- >>> pl @ToList (M.fromList (zip ['a'..] [9,2,7,4]))
+-- Present [9,2,7,4] (ToList fromList [('a',9),('b',2),('c',7),('d',4)])
+-- PresentT [9,2,7,4]
+--
+
+data ToList
+instance (Show (t a)
+        , Foldable t
+        ) => P ToList (t a) where
+  type PP ToList (t a) = [a]
+  eval _ opts as =
+    let msg0 = "ToList"
+        z = toList as
+    in pure $ mkNode opts (PresentT z) (msg0 <> showVerbose opts " " as) []
+
+-- | similar to 'toList'
+--
+-- >>> pz @(ToList' Id) ("aBc" :: String)
+-- PresentT "aBc"
+--
+-- >>> pz @(ToList' Id) (Just 14)
+-- PresentT [14]
+--
+-- >>> pz @(ToList' Id) Nothing
+-- PresentT []
+--
+-- >>> pz @(ToList' Id) (Left ("xx" :: String))
+-- PresentT []
+--
+-- >>> pz @(ToList' Id) (These 12 ("xx" :: String))
+-- PresentT ["xx"]
+--
+data ToList' p
+
+instance (PP p x ~ t a
+        , P p x
+        , Show (t a)
+        , Foldable t
+        , Show a
+        ) => P (ToList' p) x where
+  type PP (ToList' p) x = [ExtractAFromTA (PP p x)] -- extra layer of indirection means pan (ToList' Id) "abc" won't work without setting the type of "abc" unlike ToList
+  eval _ opts x = do
+    let msg0 = "ToList'"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let hhs = [hh pp]
+            b = toList p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) hhs
+
+data Null' p
+
+instance (Show (t a)
+        , Foldable t
+        , t a ~ PP p x
+        , P p x
+        ) => P (Null' p) x where
+  type PP (Null' p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Null"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = null p
+        in mkNodeB opts b ("Null" <> showVerbose opts " | " p) [hh pp]
+
+-- | similar to 'null' using 'Foldable'
+--
+-- >>> pz @Null [1,2,3,4]
+-- FalseT
+--
+-- >>> pz @Null []
+-- TrueT
+--
+-- >>> pz @Null Nothing
+-- TrueT
+--
+data Null
+type NullT = Null' Id
+instance P NullT a => P Null a where
+  type PP Null a = Bool
+  eval _ = evalBool (Proxy @NullT)
+
+-- | similar to a limited form of 'foldMap'
+--
+-- >>> pz @(FoldMap (SG.Sum _) Id) [44, 12, 3]
+-- PresentT 59
+--
+-- >>> pz @(FoldMap (SG.Product _) Id) [44, 12, 3]
+-- PresentT 1584
+--
+-- >>> type Ands' p = FoldMap SG.All p
+-- >>> pz @(Ands' Id) [True,False,True,True]
+-- PresentT False
+--
+-- >>> pz @(Ands' Id) [True,True,True]
+-- PresentT True
+--
+-- >>> pz @(Ands' Id) []
+-- PresentT True
+--
+-- >>> type Ors' p = FoldMap SG.Any p
+-- >>> pz @(Ors' Id) [False,False,False]
+-- PresentT False
+--
+-- >>> pz @(Ors' Id) []
+-- PresentT False
+--
+-- >>> pz @(Ors' Id) [False,False,False,True]
+-- PresentT True
+--
+-- >>> type AllPositive' = FoldMap SG.All (Map Positive Id)
+-- >>> pz @AllPositive' [3,1,-5,10,2,3]
+-- PresentT False
+--
+-- >>> type AllNegative' = FoldMap SG.All (Map Negative Id)
+-- >>> pz @AllNegative' [-1,-5,-10,-2,-3]
+-- PresentT True
+--
+-- >>> :set -XKindSignatures
+-- >>> type Max' (t :: Type) = FoldMap (SG.Max t) Id -- requires t be Bounded for monoid instance
+-- >>> pz @(Max' Int) [10,4,5,12,3,4]
+-- PresentT 12
+--
+-- >>> pl @(FoldMap (SG.Sum _) Id) [14,8,17,13]
+-- Present 52 ((>>) 52 | {getSum = 52})
+-- PresentT 52
+--
+-- >>> pl @(FoldMap (SG.Max _) Id) [14 :: Int,8,17,13] -- cos Bounded!
+-- Present 17 ((>>) 17 | {getMax = 17})
+-- PresentT 17
+--
+-- >>> pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) [1..20]
+-- True (False || True)
+-- TrueT
+--
+-- >>> pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) [1..19]
+-- False (False || False | ((>>) False | {1 == 0})}) || ((>>) False | {190 > 200}))
+-- FalseT
+--
+-- >>> pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) []
+-- True (True || False)
+-- TrueT
+--
+-- >>> pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) &&& FoldMap (SG.Sum _) Id) [1..20]
+-- Present (False,210) (W '(False,210))
+-- PresentT (False,210)
+--
+-- >>> pl @(FoldMap SG.Any Id) [False,False,True,False]
+-- Present True ((>>) True | {getAny = True})
+-- PresentT True
+--
+-- >>> pl @(FoldMap SG.All Id) [False,False,True,False]
+-- Present False ((>>) False | {getAll = False})
+-- PresentT False
+--
+-- >>> pl @(FoldMap (SG.Sum _) Id) (Just 13)
+-- Present 13 ((>>) 13 | {getSum = 13})
+-- PresentT 13
+--
+-- >>> pl @(FoldMap (SG.Sum _) Id) [1..10]
+-- Present 55 ((>>) 55 | {getSum = 55})
+-- PresentT 55
+--
+
+data FoldMap (t :: Type) p
+type FoldMapT (t :: Type) p = Map (Wrap t Id) p >> Unwrap (MConcat Id)
+
+instance P (FoldMapT t p) x => P (FoldMap t p) x where
+  type PP (FoldMap t p) x = PP (FoldMapT t p) x
+  eval _ = eval (Proxy @(FoldMapT t p))
+
+ src/Predicate/Data/IO.hs view
@@ -0,0 +1,326 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+   promoted io functions
+-}
+module Predicate.Data.IO (
+
+    ReadFile
+  , FileExists
+  , ReadDir
+  , DirExists
+  , ReadEnv
+  , ReadEnvAll
+  , TimeUtc
+  , TimeZt
+  , AppendFile
+  , WriteFile
+  , WriteFile'
+  , Stdout
+  , Stderr
+  , Stdin
+  , ReadIO
+  , ReadIO'
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Maybe (IsJust)
+import Predicate.Data.Monoid (type (<>))
+import Predicate.Data.ReadShow (ReadP)
+import GHC.TypeLits (Symbol,KnownSymbol)
+import Data.Proxy
+import qualified Control.Exception as E
+import Data.Kind (Type)
+import Control.Arrow
+import Data.Time
+import System.Directory
+import System.IO
+import System.Environment
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+
+-- | similar to 'readFile'
+--
+-- >>> pz @(ReadFile "LICENSE" >> 'Just Id >> Len > 0) ()
+-- TrueT
+--
+-- >>> pz @(FileExists "xyzzy") ()
+-- FalseT
+--
+-- >>> pl @(FileExists "xxy") ()
+-- False (IsJust)
+-- FalseT
+--
+data ReadFile p
+
+
+-- | similar to 'doesFileExist'
+data FileExists p
+type FileExistsT p = IsJust (ReadFile p)
+
+instance P (FileExistsT p) x => P (FileExists p) x where
+  type PP (FileExists p) x = PP (FileExistsT p) x
+  eval _ = evalBool (Proxy @(FileExistsT p))
+
+instance ( PP p x ~ String
+         , P p x
+         ) => P (ReadFile p) x where
+  type PP (ReadFile p) x = Maybe String
+  eval _ opts x = do
+    let msg0 = "ReadFile"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        let msg1 = msg0 <> "[" <> p <> "]"
+        mb <- runIO $ do
+                b <- doesFileExist p
+                if b then Just <$> readFile p
+                else pure Nothing
+        pure $ case mb of
+          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
+          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
+          Just (Just b) -> mkNode opts (PresentT (Just b)) (msg1 <> " len=" <> show (length b) <> " Just " <> litL opts b) [hh pp]
+
+-- | similar to 'doesDirectoryExist'
+--
+-- >>> pz @(DirExists ".") ()
+-- TrueT
+--
+-- >>> pl @(DirExists ".") ()
+-- True (IsJust)
+-- TrueT
+--
+-- >>> pl @(DirExists "xxy") ()
+-- False (IsJust)
+-- FalseT
+--
+data DirExists p
+type DirExistsT p = IsJust (ReadDir p)
+
+instance P (DirExistsT p) x => P (DirExists p) x where
+  type PP (DirExists p) x = PP (DirExistsT p) x
+  eval _ = evalBool (Proxy @(DirExistsT p))
+
+-- | similar to 'listDirectory'
+data ReadDir p
+instance ( PP p x ~ String
+         , P p x
+         ) => P (ReadDir p) x where
+  type PP (ReadDir p) x = Maybe [FilePath]
+  eval _ opts x = do
+    let msg0 = "ReadDir"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        let msg1 = msg0 <> "[" <> p <> "]"
+        mb <- runIO $ do
+                b <- doesDirectoryExist p
+                if b then Just <$> listDirectory p
+                else pure Nothing
+        pure $ case mb of
+          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
+          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
+          Just (Just b) -> mkNode opts (PresentT (Just b)) (msg1 <> " len=" <> show (length b) <> " Just " <> showL opts b) [hh pp]
+
+-- | read an environment variable: similar to 'getEnv'
+--
+-- >>> pz @(ReadEnv "PATH" >> 'Just Id >> 'True) ()
+-- TrueT
+--
+data ReadEnv p
+
+instance ( PP p x ~ String
+         , P p x
+         ) => P (ReadEnv p) x where
+  type PP (ReadEnv p) x = Maybe String
+  eval _ opts x = do
+    let msg0 = "ReadEnv"
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        let msg1 = msg0 <> "[" <> p <> "]"
+        mb <- runIO $ lookupEnv p
+        pure $ case mb of
+          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
+          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
+          Just (Just v) -> mkNode opts (PresentT (Just v)) (msg1 <> " " <> litL opts v) [hh pp]
+
+-- | read all the environment variables as key value pairs: similar to 'getEnvironment'
+data ReadEnvAll
+
+instance P ReadEnvAll a where
+  type PP ReadEnvAll a = [(String,String)]
+  eval _ opts _ = do
+    let msg0 = "ReadEnvAll"
+    mb <- runIO getEnvironment
+    pure $ case mb of
+      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
+      Just v -> mkNode opts (PresentT v) (msg0 <> " count=" <> show (length v)) []
+
+-- | get the current time using 'UTCTime'
+data TimeUtc
+
+instance P TimeUtc a where
+  type PP TimeUtc a = UTCTime
+  eval _ opts _a = do
+    let msg0 = "TimeUtc"
+    mb <- runIO getCurrentTime
+    pure $ case mb of
+      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
+      Just v -> mkNode opts (PresentT v) (msg0 <> " " <> showL opts v) []
+
+-- | get the current time using 'ZonedTime'
+data TimeZt
+
+instance P TimeZt a where
+  type PP TimeZt a = ZonedTime
+  eval _ opts _a = do
+    let msg0 = "TimeZt"
+    mb <- runIO getZonedTime
+    pure $ case mb of
+      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
+      Just v -> mkNode opts (PresentT v) (msg0 <> " " <> showL opts v) []
+
+data FHandle s = FStdout | FStderr | FOther !s !WFMode deriving Show
+
+class GetFHandle (x :: FHandle Symbol) where getFHandle :: FHandle String
+instance GetFHandle 'FStdout where getFHandle = FStdout
+instance GetFHandle 'FStderr where getFHandle = FStderr
+instance (GetMode w, KnownSymbol s) => GetFHandle ('FOther s w) where getFHandle = FOther (symb @s) (getMode @w)
+
+data WFMode = WFAppend | WFWrite | WFWriteForce deriving (Show,Eq)
+
+class GetMode (x :: WFMode) where getMode :: WFMode
+instance GetMode 'WFAppend where getMode = WFAppend
+instance GetMode 'WFWriteForce where getMode = WFWriteForce
+instance GetMode 'WFWrite where getMode = WFWrite
+
+data WriteFileImpl (hh :: FHandle Symbol) p
+
+-- | append to a file
+data AppendFile (s :: Symbol) p
+type AppendFileT (s :: Symbol) p = WriteFileImpl ('FOther s 'WFAppend) p
+
+instance P (AppendFileT s p) x => P (AppendFile s p) x where
+  type PP (AppendFile s p) x = PP (AppendFileT s p) x
+  eval _ = eval (Proxy @(AppendFileT s p))
+
+
+-- | write to file, overwriting if needed
+data WriteFile' (s :: Symbol) p
+type WriteFileT' (s :: Symbol) p = WriteFileImpl ('FOther s 'WFWriteForce) p
+
+instance P (WriteFileT' s p) x => P (WriteFile' s p) x where
+  type PP (WriteFile' s p) x = PP (WriteFileT' s p) x
+  eval _ = eval (Proxy @(WriteFileT' s p))
+
+-- | write to file, without overwriting
+data WriteFile (s :: Symbol) p
+type WriteFileT (s :: Symbol) p = WriteFileImpl ('FOther s 'WFWrite) p
+
+instance P (WriteFileT s p) x => P (WriteFile s p) x where
+  type PP (WriteFile s p) x = PP (WriteFileT s p) x
+  eval _ = eval (Proxy @(WriteFileT s p))
+
+-- | write a string value to stdout
+data Stdout p
+type StdoutT p = WriteFileImpl 'FStdout p
+
+instance P (StdoutT p) x => P (Stdout p) x where
+  type PP (Stdout p) x = PP (StdoutT p) x
+  eval _ = eval (Proxy @(StdoutT p))
+
+-- | write a string value to stderr
+data Stderr p
+type StderrT p = WriteFileImpl 'FStderr p
+
+instance P (StderrT p) x => P (Stderr p) x where
+  type PP (Stderr p) x = PP (StderrT p) x
+  eval _ = eval (Proxy @(StderrT p))
+
+instance (GetFHandle fh
+        , P p a
+        , PP p a ~ String
+        ) => P (WriteFileImpl fh p) a where
+  type PP (WriteFileImpl fh p) a = ()
+  eval _ opts a = do
+    let fh = getFHandle @fh
+        msg0 = case fh of
+                      FStdout -> "Stdout"
+                      FStderr -> "Stderr"
+                      FOther s w -> (<>("[" <> s <> "]")) $ case w of
+                         WFAppend -> "AppendFile"
+                         WFWrite -> "WriteFile"
+                         WFWriteForce -> "WriteFile'"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right ss -> do
+          mb <- runIO $ case fh of
+                  FStdout -> fmap (left show) $ E.try @E.SomeException $ putStr ss
+                  FStderr -> fmap (left show) $ E.try @E.SomeException $ putStr ss
+                  FOther s w -> do
+                     b <- doesFileExist s
+                     if b && w == WFWrite then pure $ Left $ "file [" <> s <> "] already exists"
+                     else do
+                            let md = case w of
+                                   WFAppend -> AppendMode
+                                   _ -> WriteMode
+                            fmap (left show) $ E.try @E.SomeException $ withFile s md (`hPutStr` ss)
+          pure $ case mb of
+            Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" [hh pp]
+            Just (Left e) -> mkNode opts (FailT e) (msg0 <> " " <> e) [hh pp]
+            Just (Right ()) -> mkNode opts (PresentT ()) msg0 [hh pp]
+
+-- | read in a value of a given type from stdin with a prompt: similar to 'System.IO.readIO'
+type ReadIO (t :: Type) = ReadIO' t "Enter value"
+type ReadIO' (t :: Type) s = Stdout (s <> ":") >> Stdin >> ReadP t Id
+-- eg pa @(ReadIO Int + ReadIO Int) ()
+
+-- | read a value from stdin
+data Stdin
+
+instance P Stdin x where
+  type PP Stdin x = String
+  eval _ opts _x = do
+    let msg0 = "Stdin"
+    mb <- runIO $ do
+                      lr <- E.try getLine
+                      pure $ case lr of
+                        Left (e :: E.SomeException) -> Left $ show e
+                        Right ss -> Right ss
+    pure $ case mb of
+      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
+      Just (Left e) -> mkNode opts (FailT e) (msg0 <> " " <> e) []
+      Just (Right ss) -> mkNode opts (PresentT ss) (msg0 <> "[" <> litVerbose opts "" ss <> "]") []
+
+ src/Predicate/Data/Index.hs view
@@ -0,0 +1,534 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted indexing functions
+-}
+module Predicate.Data.Index (
+  -- ** indexing expressions
+    Ix
+  , Ix'
+  , IxL
+  , type (!!)
+  , type (!!?)
+  , Lookup
+  , LookupDef
+  , LookupDef'
+  , LookupFail
+  , LookupFail'
+
+  -- ** list to tuples
+  , Tuple2
+  , Tuple3
+  , Tuple4
+  , Tuple5
+  , Tuple6
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Maybe (JustDef, JustFail)
+import Control.Lens hiding (iall)
+import GHC.TypeLits (Nat, KnownNat)
+import Data.Proxy
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Map.Strict as M
+-- >>> import qualified Data.Set as Set
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+
+-- | index a value in an 'Ixed' container and if not found return the given default value
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) (['a'..'e'],2)
+-- Present 'c' (JustDef Just)
+-- PresentT 'c'
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) (['a'..'e'],999)
+-- Present 'x' (JustDef Nothing)
+-- PresentT 'x'
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) ([],2)
+-- Present 'x' (JustDef Nothing)
+-- PresentT 'x'
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") (Snd Id)) ('w',([],2))
+-- Present 'x' (JustDef Nothing)
+-- PresentT 'x'
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (Fst Id) (Snd Id)) ('x',(['a'..'e'],2))
+-- Present 'c' (JustDef Just)
+-- PresentT 'c'
+--
+-- >>> pl @(LookupDef' (Fst Id) (Snd Id) (MEmptyT _) (Snd Id)) ('x',(map SG.Min [10..15::Int], 3))
+-- Present Min {getMin = 13} (JustDef Just)
+-- PresentT (Min {getMin = 13})
+--
+data LookupDef' v w p q
+type LookupDefT' v w p q = JustDef p (q >> Lookup v w)
+
+instance P (LookupDefT' v w p q) x => P (LookupDef' v w p q) x where
+  type PP (LookupDef' v w p q) x = PP (LookupDefT' v w p q) x
+  eval _ = eval (Proxy @(LookupDefT' v w p q))
+
+-- | index a value in an 'Ixed' container and if not found return the given default value
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 4 Id) 23
+-- Present 5 (JustDef Just)
+-- PresentT 5
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 4 (Fst Id)) (23,'x')
+-- Present 5 (JustDef Just)
+-- PresentT 5
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 99 Id) 23
+-- Present 23 (JustDef Nothing)
+-- PresentT 23
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 99 (Fst Id)) (23,'x')
+-- Present 23 (JustDef Nothing)
+-- PresentT 23
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 4 999) (23,'x')
+-- Present 5 (JustDef Just)
+-- PresentT 5
+--
+-- >>> pl @(LookupDef '[1,2,3,4,5,6] 40 999) (23,'x')
+-- Present 999 (JustDef Nothing)
+-- PresentT 999
+--
+-- >>> pl @(LookupDef (Fst Id) 4 (MEmptyT _)) (map SG.Min [1::Int .. 10],'x')
+-- Present Min {getMin = 5} (JustDef Just)
+-- PresentT (Min {getMin = 5})
+--
+-- >>> pl @(LookupDef (Fst Id) 999 (MEmptyT _)) (map SG.Min [1::Int .. 10],'x')
+-- Present Min {getMin = 9223372036854775807} (JustDef Nothing)
+-- PresentT (Min {getMin = 9223372036854775807})
+--
+data LookupDef v w p
+type LookupDefT v w p = LookupDef' v w p I
+
+instance P (LookupDefT v w p) x => P (LookupDef v w p) x where
+  type PP (LookupDef v w p) x = PP (LookupDefT v w p) x
+  eval _ = eval (Proxy @(LookupDefT v w p))
+
+-- | index a value in an 'Ixed' container and if not found fail with the given message
+data LookupFail' msg v w q
+type LookupFailT' msg v w q = JustFail msg (q >> Lookup v w)
+
+instance P (LookupFailT' msg v w q) x => P (LookupFail' msg v w q) x where
+  type PP (LookupFail' msg v w q) x = PP (LookupFailT' msg v w q) x
+  eval _ = eval (Proxy @(LookupFailT' msg v w q))
+
+-- | index a value in an 'Ixed' container and if not found fail with the given message
+--
+-- >>> pl @(LookupFail "someval" (Fst Id) 999) (map SG.Min [1::Int .. 10],'x')
+-- Error someval (JustFail Nothing)
+-- FailT "someval"
+--
+-- >>> pl @(LookupFail (PrintF "char=%c" (Snd Id)) (Fst Id) 49) (map SG.Min [1::Int ..10],'x')
+-- Error char=x (JustFail Nothing)
+-- FailT "char=x"
+--
+data LookupFail msg v w
+type LookupFailT msg v w = LookupFail' msg v w I
+
+instance P (LookupFailT msg v w) x => P (LookupFail msg v w) x where
+  type PP (LookupFail msg v w) x = PP (LookupFailT msg v w) x
+  eval _ = eval (Proxy @(LookupFailT msg v w))
+
+-- | similar to 'Data.List.!!' using an 'Ixed' container
+--
+-- >>> pz @(Ix 4 "not found") ["abc","D","eF","","G"]
+-- PresentT "G"
+--
+-- >>> pz @(Ix 40 "not found") ["abc","D","eF","","G"]
+-- PresentT "not found"
+--
+-- >>> pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Id) ([10,12,3,5],"ss")
+-- Present (12,5) ((>>) (12,5) | {Id (12,5)})
+-- PresentT (12,5)
+--
+-- >>> pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Fst Id < Snd Id) ([10,12,3,5],"ss")
+-- False ((>>) False | {12 < 5})
+-- FalseT
+--
+-- >>> pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Fst Id > Snd Id) ([10,12,3,5],"ss")
+-- True ((>>) True | {12 > 5})
+-- TrueT
+--
+-- >>> pl @(Snd Id >> Len &&& Ix 3 (Failp "someval1") >> Fst Id == Snd Id) ('x',[1..5])
+-- False ((>>) False | {5 == 4})
+-- FalseT
+--
+-- >>> pl @(Snd Id >> Len &&& Ix 3 (Failp "someval2") >> Fst Id < Snd Id) ('x',[1..5])
+-- False ((>>) False | {5 < 4})
+-- FalseT
+--
+-- >>> pl @(Snd Id >> Len &&& Ix 3 (Failp "someval3") >> Fst Id > Snd Id) ('x',[1..5])
+-- True ((>>) True | {5 > 4})
+-- TrueT
+--
+-- >>> pl @(Map Len Id >> Ix 3 (Failp "lhs") &&& Ix 0 5 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- Error lhs ([4,2] (>>) rhs failed)
+-- FailT "lhs"
+--
+-- >>> pl @(Map Len Id >> Ix 0 (Failp "lhs") &&& Ix 1 5 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- False ((>>) False | {4 == 2})
+-- FalseT
+--
+-- >>> pl @(Map Len Id >> Ix 1 (Failp "lhs") &&& Ix 3 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- Error rhs ([4,2] (>>) rhs failed)
+-- FailT "rhs"
+--
+-- >>> pl @(Map Len Id >> Ix 10 (Failp "lhs") &&& Ix 1 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- Error lhs ([4,2] (>>) rhs failed)
+-- FailT "lhs"
+--
+-- >>> pl @(Map Len Id >> Ix 0 (Failp "lhs") &&& Ix 10 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- Error rhs ([4,2] (>>) rhs failed)
+-- FailT "rhs"
+--
+-- >>> pl @(Map Len Id >> Ix 10 3 &&& Ix 1 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- False ((>>) False | {3 == 2})
+-- FalseT
+--
+-- >>> pl @(Map Len Id >> Ix 3 3 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- False ((>>) False | {3 == 2})
+-- FalseT
+--
+-- >>> pl @(Map Len Id >> Ix 10 3 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- False ((>>) False | {3 == 2})
+-- FalseT
+--
+-- >>> pl @(Map Len Id >> Ix 10 5 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- False ((>>) False | {5 == 2})
+-- FalseT
+--
+-- >>> pl @(Map Len Id >> Ix 10 2 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
+-- True ((>>) True | {2 == 2})
+-- TrueT
+--
+data Ix (n :: Nat) def
+
+instance (P def (Proxy a)
+        , PP def (Proxy a) ~ a
+        , KnownNat n
+        , Show a
+        ) => P (Ix n def) [a] where
+  type PP (Ix n def) [a] = a
+  eval _ opts as = do
+    let n = nat @n
+        msg0 = "Ix(" <> show n <> ")"
+    case as ^? ix n of
+         Nothing -> do
+           let msg1 = msg0 <> " not found"
+           pp <- eval (Proxy @def) opts (Proxy @a)
+           pure $ case getValueLR opts msg1 pp [] of
+             Left e -> e
+             Right _ -> mkNode opts (_tBool pp) msg1 [hh pp]
+         Just a -> pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+data Ix' (n :: Nat)
+type IxT' (n :: Nat) = Ix n (Failp "Ix index not found")
+
+instance P (IxT' n) x => P (Ix' n) x where
+  type PP (Ix' n) x = PP (IxT' n) x
+  eval _ = eval (Proxy @(IxT' n))
+
+-- | similar to 'Data.List.!!' leveraging 'Ixed'
+--
+-- >>> pz @(IxL Id 2 "notfound") ["abc","D","eF","","G"]
+-- PresentT "eF"
+--
+-- >>> pz @(IxL Id 20 "notfound") ["abc","D","eF","","G"]
+-- PresentT "notfound"
+--
+-- >>> pl @(IxL Id 1 (Char1 "x")) ("123" :: T.Text)
+-- Present '2' (IxL(1) '2' | p="123" | q=1)
+-- PresentT '2'
+--
+-- >>> pl @(IxL Id 15 (Char1 "x")) ("123" :: T.Text)
+-- Present 'x' (IxL(15) index not found)
+-- PresentT 'x'
+--
+
+data IxL p q def -- p is the big value and q is the index and def is the default
+
+instance (P q a
+        , P p a
+        , Show (PP p a)
+        , Ixed (PP p a)
+        , PP q a ~ Index (PP p a)
+        , Show (Index (PP p a))
+        , Show (IxValue (PP p a))
+        , P r (Proxy (IxValue (PP p a)))
+        , PP r (Proxy (IxValue (PP p a))) ~ IxValue (PP p a)
+        )
+   => P (IxL p q r) a where
+  type PP (IxL p q r) a = IxValue (PP p a)
+  eval _ opts a = do
+    let msg0 = "IxL"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> "(" <> show q <> ")"
+        in case p ^? ix q of
+             Nothing -> do
+                rr <- eval (Proxy @r) opts (Proxy @(IxValue (PP p a)))
+                pure $ case getValueLR opts msg1 rr [hh pp, hh qq] of
+                  Left e -> e
+                  Right _ -> mkNode opts (_tBool rr) (msg1 <> " index not found") [hh pp, hh qq]
+             Just ret -> pure $ mkNode opts (PresentT ret) (show01' opts msg1 ret "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | similar to 'Data.List.!!' leveraging 'Ixed'
+--
+-- >>> pz @(Id !! 2) ["abc","D","eF","","G"]
+-- PresentT "eF"
+--
+-- >>> pz @(Id !! 20) ["abc","D","eF","","G"]
+-- FailT "(!!) index not found"
+--
+-- >>> pz @(Id !! "eF") (M.fromList (flip zip [0..] ["abc","D","eF","","G"]))
+-- PresentT 2
+--
+-- >>> pl @(Id !! 3) ("asfd" :: T.Text)
+-- Present 'd' (IxL(3) 'd' | p="asfd" | q=3)
+-- PresentT 'd'
+--
+-- >>> pl @(Id !! 4) ("asfd" :: T.Text)
+-- Error (!!) index not found (IxL(4))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(Id !! MEmptyT _) (Just "a")
+-- Present "a" (IxL(()) "a" | p=Just "a" | q=())
+-- PresentT "a"
+--
+-- >>> pl @(Id !! MEmptyT _) (Nothing @()) -- had to add @() to keep this happy: ghci is fine
+-- Error (!!) index not found (IxL(()))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(Id !! 0) ('a','b','c')
+-- Present 'a' (IxL(0) 'a' | p=('a','b','c') | q=0)
+-- PresentT 'a'
+--
+-- >>> pl @(Id !! Failt _ "err") ('a','b','c')
+-- Error err (IxL)
+-- FailT "err"
+--
+-- >>> pl @(Id !! "d") (M.fromList $ zip (map (:[]) "abcd") [0 ..])
+-- Present 3 (IxL("d") 3 | p=fromList [("a",0),("b",1),("c",2),("d",3)] | q="d")
+-- PresentT 3
+--
+-- >>> pl @(Id !! Head "d") (M.fromList $ zip "abcd" [0 ..]) -- had to String (instead of _) to keep this happy: ghci is fine
+-- Present 3 (IxL('d') 3 | p=fromList [('a',0),('b',1),('c',2),('d',3)] | q='d')
+-- PresentT 3
+--
+-- >>> pl @(Id !! Head "d") (Set.fromList "abcd") -- had to String (instead of _) to keep this happy: ghci is fine
+-- Present () (IxL('d') () | p=fromList "abcd" | q='d')
+-- PresentT ()
+--
+-- >>> pl @(Id !! HeadFail "failedn" "e") (Set.fromList "abcd") -- had to String (instead of _) to keep this happy: ghci is fine
+-- Error (!!) index not found (IxL('e'))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(Id !! Head "d") (M.fromList $ zip "abcd" [0 ..])   -- use Char1 "d" instead of "d" >> Head
+-- Present 3 (IxL('d') 3 | p=fromList [('a',0),('b',1),('c',2),('d',3)] | q='d')
+-- PresentT 3
+--
+-- >>> pl @(Id !! MEmptyT _) (Just 10)
+-- Present 10 (IxL(()) 10 | p=Just 10 | q=())
+-- PresentT 10
+--
+-- >>> pl @(Id !! MEmptyT _) (Nothing @())
+-- Error (!!) index not found (IxL(()))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(Id !! 6) ['a'..'z']
+-- Present 'g' (IxL(6) 'g' | p="abcdefghijklmnopqrstuvwxyz" | q=6)
+-- PresentT 'g'
+--
+-- >>> pl @(Snd Id !! Fst Id) (3,"abcde" :: String)
+-- Present 'd' (IxL(3) 'd' | p="abcde" | q=3)
+-- PresentT 'd'
+--
+-- >>> pl @(Snd Id !! Fst Id) (4,[9,8])
+-- Error (!!) index not found (IxL(4))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(2 &&& Id >> Snd Id !! Fst Id) ("abcdef" :: String)
+-- Present 'c' ((>>) 'c' | {IxL(2) 'c' | p="abcdef" | q=2})
+-- PresentT 'c'
+--
+-- >>> pl @((Len >> Pred Id) &&& Id >> Snd Id !! Fst Id) "abcdef"
+-- Present 'f' ((>>) 'f' | {IxL(5) 'f' | p="abcdef" | q=5})
+-- PresentT 'f'
+--
+-- >>> pl @(Id !! 3) ('a','b','c','d','e')
+-- Present 'd' (IxL(3) 'd' | p=('a','b','c','d','e') | q=3)
+-- PresentT 'd'
+--
+-- >>> pl @(Id !! "s") $ M.fromList [("t",1), ("s", 20), ("s", 99)]
+-- Present 99 (IxL("s") 99 | p=fromList [("s",99),("t",1)] | q="s")
+-- PresentT 99
+--
+-- >>> pl @(Id !! Char1 "d") (M.fromList $ zip "abcd" [0 ..])
+-- Present 3 (IxL('d') 3 | p=fromList [('a',0),('b',1),('c',2),('d',3)] | q='d')
+-- PresentT 3
+--
+-- >>> pl @(Id !! FromString _ "d" &&& (Map (Snd Id >> Gt 3 >> Coerce SG.Any) (IToList _ Id) >> MConcat Id)) (M.fromList $ zip (map T.singleton "abcdefgh") [0 ..])
+-- Present (3,Any {getAny = True}) (W '(3,Any {getAny = True}))
+-- PresentT (3,Any {getAny = True})
+--
+-- >>> pl @(Id !! FromString _ "d" &&& (Map (Snd Id >> Gt 3 >> Wrap SG.Any Id) (IToList _ Id) >> MConcat Id >> Unwrap Id)) (M.fromList $ zip (map T.singleton "abcdefgh") [0 ..])
+-- Present (3,True) (W '(3,True))
+-- PresentT (3,True)
+--
+-- >>> pl @(Id !! FromString _ "d") (M.fromList $ zip (map T.singleton "abcd") [0 ..])
+-- Present 3 (IxL("d") 3 | p=fromList [("a",0),("b",1),("c",2),("d",3)] | q="d")
+-- PresentT 3
+--
+-- >>> pl @(Id !! FromString _ "d") (M.fromList $ zip (map T.singleton "abcd") [0 ..])
+-- Present 3 (IxL("d") 3 | p=fromList [("a",0),("b",1),("c",2),("d",3)] | q="d")
+-- PresentT 3
+--
+-- >>> pl @(Id !! 2 !! 0) [[1..5],[10..14],[100..110]]
+-- Present 100 (IxL(0) 100 | p=[100,101,102,103,104,105,106,107,108,109,110] | q=0)
+-- PresentT 100
+--
+-- >>> pl @(Id !! 1 !! 7) [[1..5],[10..14],[100..110]]
+-- Error (!!) index not found (IxL(7))
+-- FailT "(!!) index not found"
+--
+-- >>> pl @(Id !! 1) [('x',14),('y',3),('z',5)]
+-- Present ('y',3) (IxL(1) ('y',3) | p=[('x',14),('y',3),('z',5)] | q=1)
+-- PresentT ('y',3)
+--
+-- >>> pl @(Id !! 14) [('x',14),('y',3),('z',5)]
+-- Error (!!) index not found (IxL(14))
+-- FailT "(!!) index not found"
+--
+
+data p !! q
+type BangBangT p q = IxL p q (Failp "(!!) index not found")
+
+instance P (BangBangT p q) a => P (p !! q) a where
+  type PP (p !! q) a = PP (BangBangT p q) a
+  eval _ = eval (Proxy @(BangBangT p q))
+
+-- | 'lookup' leveraging 'Ixed'
+--
+-- >>> pz @(Lookup Id 2) ["abc","D","eF","","G"]
+-- PresentT (Just "eF")
+--
+-- >>> pz @(Lookup Id 20) ["abc","D","eF","","G"]
+-- PresentT Nothing
+--
+-- >>> pl @(FromList (M.Map _ _) >> Lookup Id (Char1 "y")) [('x',True),('y',False)]
+-- Present Just False ((>>) Just False | {Lookup('y') False | p=fromList [('x',True),('y',False)] | q='y'})
+-- PresentT (Just False)
+--
+-- >>> pl @(FromList (M.Map _ _) >> Lookup Id (Char1 "z")) [('x',True),('y',False)]
+-- Present Nothing ((>>) Nothing | {Lookup('z') not found})
+-- PresentT Nothing
+--
+-- >>> pl @(FromList (M.Map _ _) >> Lookup Id %% Char1 "y") [('x',True),('y',False)]
+-- Present Just False ((>>) Just False | {Lookup('y') False | p=fromList [('x',True),('y',False)] | q='y'})
+-- PresentT (Just False)
+--
+-- >>> pl @(Lookup Id 1) [('x',14),('y',3),('z',5)]
+-- Present Just ('y',3) (Lookup(1) ('y',3) | p=[('x',14),('y',3),('z',5)] | q=1)
+-- PresentT (Just ('y',3))
+--
+-- >>> pl @(Lookup Id 14) [('x',14),('y',3),('z',5)]
+-- Present Nothing (Lookup(14) not found)
+-- PresentT Nothing
+--
+-- >>> pl @(Lookup "abcdef" 3) ()
+-- Present Just 'd' (Lookup(3) 'd' | p="abcdef" | q=3)
+-- PresentT (Just 'd')
+--
+-- >>> pl @(Lookup '[1,2,3,4,5,6] 4) ()
+-- Present Just 5 (Lookup(4) 5 | p=[1,2,3,4,5,6] | q=4)
+-- PresentT (Just 5)
+--
+-- >>> pl @(FromList (M.Map _ _)) [(4,"x"),(5,"dd")]
+-- Present fromList [(4,"x"),(5,"dd")] (FromList fromList [(4,"x"),(5,"dd")])
+-- PresentT (fromList [(4,"x"),(5,"dd")])
+--
+data Lookup p q
+
+instance (P q a
+        , P p a
+        , Show (PP p a)
+        , Ixed (PP p a)
+        , PP q a ~ Index (PP p a)
+        , Show (Index (PP p a))
+        , Show (IxValue (PP p a))
+        )
+   => P (Lookup p q) a where
+  type PP (Lookup p q) a = Maybe (IxValue (PP p a))
+  eval _ opts a = do
+    let msg0 = "Lookup"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> "(" <> show q <> ")"
+            hhs = [hh pp, hh qq]
+        in case p ^? ix q of
+             Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " not found") hhs
+             Just ret -> mkNode opts (PresentT (Just ret)) (show01' opts msg1 ret "p=" p <> showVerbose opts " | q=" q) hhs
+
+-- | type operator version of 'Lookup'
+--
+-- >>> pl @((Id !!? Char1 "d") > MkJust 99 || Length Id <= 3) (M.fromList $ zip "abcd" [1..])
+-- False (False || False | (Just 4 > Just 99) || (4 <= 3))
+-- FalseT
+--
+-- >>> pz @((Id !!? Char1 "d") > MkJust 2 || Length Id <= 3) (M.fromList $ zip "abcd" [1..])
+-- TrueT
+--
+data p !!? q
+type BangBangQT p q = Lookup p q
+
+instance P (BangBangQT p q) a => P (p !!? q) a where
+  type PP (p !!? q) a = PP (BangBangQT p q) a
+  eval _ = eval (Proxy @(BangBangQT p q))
+
+-- | convert a list to a 2-tuple
+type Tuple2 p = '(p !! 0, p !! 1)
+-- | convert a list to a 3-tuple
+type Tuple3 p = '(p !! 0, p !! 1, p !! 2)
+-- | convert a list to a 4-tuple
+type Tuple4 p = '(p !! 0, p !! 1, p !! 2, p !! 3)
+-- | convert a list to a 5-tuple
+type Tuple5 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4)
+-- | convert a list to a 6-tuple
+type Tuple6 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4, p !! 5)
+ src/Predicate/Data/Iterator.hs view
@@ -0,0 +1,594 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted iterator functions
+-}
+module Predicate.Data.Iterator (
+    Scanl
+  , ScanN
+  , ScanNA
+  , FoldN
+  , Foldl
+  , Unfoldr
+  , IterateUntil
+  , IterateWhile
+  , IterateNWhile
+  , IterateNUntil
+
+  , Para
+  , ParaN
+
+  , DoN
+  , Repeat
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Tuple (type (***))
+import Predicate.Data.Ordering (type (>))
+import Predicate.Data.Enum (type (...), Pred)
+import Predicate.Data.List (Last)
+import Predicate.Data.Maybe (MaybeBool)
+import GHC.TypeLits (Nat, KnownNat)
+import qualified GHC.TypeLits as GL
+import Control.Lens hiding (iall)
+import Data.Proxy
+import Data.Maybe
+import Control.Arrow
+import Data.Void
+
+-- $setup
+-- >>> import Predicate.Prelude
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XAllowAmbiguousTypes
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> :set -XFlexibleContexts
+-- >>> import Data.Time
+
+-- want to pass Proxy b to q but then we have no way to calculate 'b'
+
+-- | similar to 'scanl'
+--
+-- >>> pz @(Scanl (Snd Id :+ Fst Id) (Fst Id) (Snd Id)) ([99],[1..5])
+-- PresentT [[99],[1,99],[2,1,99],[3,2,1,99],[4,3,2,1,99],[5,4,3,2,1,99]]
+--
+-- >>> pl @(Scanl (Snd Id :+ Fst Id) (Fst Id) (Snd Id)) ([99],[])
+-- Present [[99]] (Scanl [[99]] | b=[99] | as=[])
+-- PresentT [[99]]
+--
+
+data Scanl p q r
+-- scanr :: (a -> b -> b) -> b -> [a] -> [b]
+-- result is scanl but signature is flipped ((a,b) -> b) -> b -> [a] -> [b]
+
+instance (PP p (b,a) ~ b
+        , PP q x ~ b
+        , PP r x ~ [a]
+        , P p (b,a)
+        , P q x
+        , P r x
+        , Show b
+        , Show a
+        )
+     => P (Scanl p q r) x where
+  type PP (Scanl p q r) x = [PP q x]
+  eval _ opts z = do
+    let msg0 = "Scanl"
+    lr <- runPQ msg0 (Proxy @q) (Proxy @r) opts z []
+    case lr of
+      Left e -> pure e
+      Right (q,r,qq,rr) ->
+        case chkSize opts msg0 r [hh rr] of
+          Left e -> pure e
+          Right () -> do
+            let ff i b as' rs
+                   | i >= oRecursion opts = pure (rs, Left $ mkNode opts (FailT (msg0 <> ":recursion limit i=" <> showIndex i)) ("(b,as')=" <> showL opts (b,as')) [])
+                   | otherwise =
+                       case as' of
+                         [] -> pure (rs, Right ()) -- ++ [((i,q), mkNode opts (PresentT q) (msg0 <> "(done)") [])], Right ())
+                         a:as -> do
+                            pp :: TT b <- evalHide @p opts (b,a)
+                            case getValueLR opts (msg0 <> " i=" <> showIndex i <> " a=" <> show a) pp [] of
+                               Left e  -> pure (rs,Left e)
+                               Right b' -> ff (i+1) b' as (rs ++ [((i,b), pp)])
+            (ts,lrx) :: ([((Int, b), TT b)], Either (TT [b]) ()) <- ff 1 q r []
+            pure $ case splitAndAlign opts msg0 (((0,q), mkNode opts (PresentT q) (msg0 <> "(initial)") []) : ts) of
+                 Left e -> errorInProgram $ "Scanl e=" ++ show (fromTT e)
+                 Right abcs ->
+                   let vals = map (view _1) abcs
+                       itts = map (view _2 &&& view _3) abcs
+                   in case lrx of
+                        Left e -> mkNode opts (_tBool e) msg0 (hh qq : hh rr : map (hh . fixit) itts ++ [hh e])
+                        Right () -> mkNode opts (PresentT vals) (show01' opts msg0 vals "b=" q <> showVerbose opts " | as=" r) (hh qq : hh rr : map (hh . fixit) itts)
+
+-- | iterates n times keeping all the results
+--
+-- >>> pz @(ScanN 4 (Succ Id) Id) 'c'
+-- PresentT "cdefg"
+--
+-- >>> pz @(Dup >> ScanN 4 (Pred Id *** Succ Id) Id) 'g'
+-- PresentT [('g','g'),('f','h'),('e','i'),('d','j'),('c','k')]
+--
+-- >>> pz @(ScanN 4 (Succ Id) Id) 4
+-- PresentT [4,5,6,7,8]
+--
+-- >>> pz @('(0,1) >> ScanN 20 '(Snd Id, Fst Id + Snd Id) Id >> Map (Fst Id) Id) "sdf"
+-- PresentT [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
+--
+-- >>> pl @(ScanN 2 (Succ Id) Id) 4
+-- Present [4,5,6] (Scanl [4,5,6] | b=4 | as=[1,2])
+-- PresentT [4,5,6]
+--
+-- >>> pl @(ScanN 5 Id Id) 4
+-- Present [4,4,4,4,4,4] (Scanl [4,4,4,4,4,4] | b=4 | as=[1,2,3,4,5])
+-- PresentT [4,4,4,4,4,4]
+--
+-- >>> pl @(ScanN 2 (Succ Id) Id >> PadR 10 (MEmptyT Ordering) Id) LT
+-- Present [LT,EQ,GT,EQ,EQ,EQ,EQ,EQ,EQ,EQ] ((>>) [LT,EQ,GT,EQ,EQ,EQ,EQ,EQ,EQ,EQ] | {PadR 10 pad=EQ [LT,EQ,GT,EQ,EQ,EQ,EQ,EQ,EQ,EQ] | [LT,EQ,GT]})
+-- PresentT [LT,EQ,GT,EQ,EQ,EQ,EQ,EQ,EQ,EQ]
+--
+-- >>> pl @(ScanN 4 (Pred Id) Id) 99
+-- Present [99,98,97,96,95] (Scanl [99,98,97,96,95] | b=99 | as=[1,2,3,4])
+-- PresentT [99,98,97,96,95]
+--
+data ScanN n p q
+type ScanNT n p q = Scanl (Fst Id >> p) q (1...n) -- n times using q then run p
+
+instance P (ScanNT n p q) x => P (ScanN n p q) x where
+  type PP (ScanN n p q) x = PP (ScanNT n p q) x
+  eval _ = eval (Proxy @(ScanNT n p q))
+
+-- | tuple version of 'ScanN'
+--
+-- >>> pl @(ScanNA (Succ Id)) (4,'a')
+-- Present "abcde" (Scanl "abcde" | b='a' | as=[1,2,3,4])
+-- PresentT "abcde"
+--
+-- >>> pl @(ScanNA (Tail Id)) (4,"abcd" :: String)
+-- Present ["abcd","bcd","cd","d",""] (Scanl ["abcd","bcd","cd","d",""] | b="abcd" | as=[1,2,3,4])
+-- PresentT ["abcd","bcd","cd","d",""]
+--
+-- >>> pl @(Len &&& Id >> ScanNA (Tail Id)) "abcd"
+-- Present ["abcd","bcd","cd","d",""] ((>>) ["abcd","bcd","cd","d",""] | {Scanl ["abcd","bcd","cd","d",""] | b="abcd" | as=[1,2,3,4]})
+-- PresentT ["abcd","bcd","cd","d",""]
+--
+data ScanNA q
+type ScanNAT q = ScanN (Fst Id) q (Snd Id)
+
+instance P (ScanNAT q) x => P (ScanNA q) x where
+  type PP (ScanNA q) x = PP (ScanNAT q) x
+  eval _ = eval (Proxy @(ScanNAT q))
+
+-- | iterates n times keeping only the last result
+--
+-- >>> pz @(FoldN 4 (Succ Id) Id) 'c'
+-- PresentT 'g'
+--
+-- >>> pz @(ReadP Day Id >> Id ... FoldN 5 (Succ Id) Id) "2020-07-27"
+-- PresentT [2020-07-27,2020-07-28,2020-07-29,2020-07-30,2020-07-31,2020-08-01]
+--
+-- >>> pl @(FoldN 2 (Succ Id) Id) LT
+-- Present GT (Last GT | [LT,EQ,GT])
+-- PresentT GT
+--
+-- >>> pl @(FoldN 30 (Succ Id) Id) LT
+-- Error Succ IO e=Prelude.Enum.Ordering.succ: bad argument (Last)
+-- FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument"
+--
+-- >>> pl @(FoldN 6 (Succ Id) Id) 'a'
+-- Present 'g' (Last 'g' | "abcdefg")
+-- PresentT 'g'
+--
+-- >>> pl @(FoldN 6 (Pred Id) Id) 'a'
+-- Present '[' (Last '[' | "a`_^]\\[")
+-- PresentT '['
+--
+-- >>> pl @(FoldN 0 (Succ Id) Id) LT
+-- Present LT (Last LT | [LT])
+-- PresentT LT
+--
+-- >>> pl @(FoldN 2 (Succ Id) Id >> FoldN 2 (Pred Id) Id) LT
+-- Present LT ((>>) LT | {Last LT | [GT,EQ,LT]})
+-- PresentT LT
+--
+-- >>> pl @(FoldN 4 ((Id &&& Id) >> SapA) Id) "abc"
+-- Present "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc" (Last "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc" | ["abc","abcabc","abcabcabcabc","abcabcabcabcabcabcabcabc","abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"])
+-- PresentT "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc"
+--
+
+data FoldN n p q
+type FoldNT n p q = Last (ScanN n p q)
+
+instance P (FoldNT n p q) x => P (FoldN n p q) x where
+  type PP (FoldN n p q) x = PP (FoldNT n p q) x
+  eval _ = eval (Proxy @(FoldNT n p q))
+
+-- | Foldl similar to 'foldl'
+--
+-- >>> pl @(Foldl (Fst Id + Snd Id) 0 (1 ... 10)) ()
+-- Present 55 (Last 55 | [0,1,3,6,10,15,21,28,36,45,55])
+-- PresentT 55
+--
+-- >>> pz @(Foldl (Snd Id :+ Fst Id) '[99] (1 ... 10)) ()
+-- PresentT [10,9,8,7,6,5,4,3,2,1,99]
+--
+-- >>> pl @(Foldl (Fst Id) '() (EnumFromTo 1 9999)) ()
+-- Error Scanl list size exceeded (Last)
+-- FailT "Scanl list size exceeded"
+--
+-- >>> pl @(Foldl (Guard "someval" (Fst Id < Snd Id) >> Snd Id) (Head Id) (Tail Id)) [1,4,7,9,16]
+-- Present 16 (Last 16 | [1,4,7,9,16])
+-- PresentT 16
+--
+-- >>> pl @(Foldl (Guard (PrintT "%d not less than %d" Id) (Fst Id < Snd Id) >> Snd Id) (Head Id) (Tail Id)) [1,4,7,6,16::Int]
+-- Error 7 not less than 6 (Last)
+-- FailT "7 not less than 6"
+--
+-- >>> pl @(Foldl (If ((Fst Id >> Fst Id) && (Snd Id > Snd (Fst Id))) '( 'True, Snd Id) '( 'False, Snd (Fst Id))) '( 'True, Head Id) (Tail Id)) [1,4,7,9,16]
+-- Present (True,16) (Last (True,16) | [(True,1),(True,4),(True,7),(True,9),(True,16)])
+-- PresentT (True,16)
+--
+-- >>> pl @(Foldl (If ((Fst Id >> Fst Id) && (Snd Id > Snd (Fst Id))) '( 'True, Snd Id) '( 'False, Snd (Fst Id))) '( 'True, Head Id) (Tail Id)) [1,4,7,9,16,2]
+-- Present (False,16) (Last (False,16) | [(True,1),(True,4),(True,7),(True,9),(True,16),(False,16)])
+-- PresentT (False,16)
+--
+-- >>> pl @(Foldl (Snd Id :+ Fst Id) (MEmptyT [_]) Id) [1..5]
+-- Present [5,4,3,2,1] (Last [5,4,3,2,1] | [[],[1],[2,1],[3,2,1],[4,3,2,1],[5,4,3,2,1]])
+-- PresentT [5,4,3,2,1]
+--
+-- >>> pl @('Just Uncons >> Foldl (If (Fst (Fst Id)) (If (Snd (Fst Id) < Snd Id) '( 'True,Snd Id) '( 'False, Snd Id)) (Fst Id)) '( 'True,Fst Id) (Snd Id)) [-10,-2,2,3,4,10,9,11]
+-- Present (False,9) ((>>) (False,9) | {Last (False,9) | [(True,-10),(True,-2),(True,2),(True,3),(True,4),(True,10),(False,9),(False,9)]})
+-- PresentT (False,9)
+--
+-- >>> pl @('Just Uncons >> Foldl (If (Fst (Fst Id)) (If (Snd (Fst Id) < Snd Id) '( 'True,Snd Id) '( 'False, Snd Id)) (Fst Id)) '( 'True,Fst Id) (Snd Id)) [-10,2,3,4,10,11]
+-- Present (True,11) ((>>) (True,11) | {Last (True,11) | [(True,-10),(True,2),(True,3),(True,4),(True,10),(True,11)]})
+-- PresentT (True,11)
+--
+
+data Foldl p q r
+type FoldLT p q r = Last (Scanl p q r)
+
+instance P (FoldLT p q r) x => P (Foldl p q r) x where
+  type PP (Foldl p q r) x = PP (FoldLT p q r) x
+  eval _ = eval (Proxy @(FoldLT p q r))
+
+-- | similar to 'Data.List.unfoldr'
+--
+-- >>> pz @(Unfoldr (MaybeBool (Not Null) (SplitAt 2 Id)) Id) [1..5]
+-- PresentT [[1,2],[3,4],[5]]
+--
+-- >>> pl @(Unfoldr (If Null (MkNothing _) ('(Take 3 Id, Drop 1 Id) >> MkJust Id)) Id) "abcdefghi"
+-- Present ["abc","bcd","cde","def","efg","fgh","ghi","hi","i"] (Unfoldr "abcdefghi" ["abc","bcd","cde","def","efg","fgh","ghi","hi","i"] | s="abcdefghi")
+-- PresentT ["abc","bcd","cde","def","efg","fgh","ghi","hi","i"]
+--
+-- >>> pl @(Unfoldr (If Null (MkNothing _) (Pure _ (SplitAt 2 Id))) Id) [1..5]
+-- Present [[1,2],[3,4],[5]] (Unfoldr [1,2,3,4,5] [[1,2],[3,4],[5]] | s=[1,2,3,4,5])
+-- PresentT [[1,2],[3,4],[5]]
+--
+-- >>> pl @(Unfoldr (MaybeBool (Not Null) (SplitAt 2 Id)) Id) [1..5]
+-- Present [[1,2],[3,4],[5]] (Unfoldr [1,2,3,4,5] [[1,2],[3,4],[5]] | s=[1,2,3,4,5])
+-- PresentT [[1,2],[3,4],[5]]
+--
+-- >>> pl @(Unfoldr (If Null (MkNothing _) (Guard "yy" (Len < 3) >> Pure _ (SplitAt 2 Id))) Id) [1..5]
+-- Error yy (Unfoldr [1,2,3,4,5])
+-- FailT "yy"
+--
+-- >>> pl @(Unfoldr (MaybeBool (Not Null) (Guard "yy" (Len < 3) >> SplitAt 2 Id)) Id) [1..5]
+-- Error yy (Unfoldr [1,2,3,4,5])
+-- FailT "yy"
+--
+-- >>> pl @(Unfoldr (Guard "xx" (Len > 4) >> Uncons) Id) [1..10]
+-- Error xx (Unfoldr [1,2,3,4,5,6,7,8,9,10])
+-- FailT "xx"
+--
+-- >>> pl @(Unfoldr Uncons Id) [1..10]
+-- Present [1,2,3,4,5,6,7,8,9,10] (Unfoldr [1,2,3,4,5,6,7,8,9,10] [1,2,3,4,5,6,7,8,9,10] | s=[1,2,3,4,5,6,7,8,9,10])
+-- PresentT [1,2,3,4,5,6,7,8,9,10]
+--
+
+data Unfoldr p q
+
+instance (PP q a ~ s
+        , PP p s ~ Maybe (b,s)
+        , P q a
+        , P p s
+        , Show s
+        , Show b
+          )
+     => P (Unfoldr p q) a where
+  type PP (Unfoldr p q) a = [UnfoldT (PP p (PP q a))]
+  eval _ opts z = do
+    let msg0 = "Unfoldr"
+    qq <- eval (Proxy @q) opts z
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q -> do
+        let msg1 = msg0 <> " " <> showL opts q
+            ff i s rs | i >= oRecursion opts = pure (rs, Left $ mkNode opts (FailT (msg1 <> ":recursion limit i=" <> showIndex i)) ("s=" <> showL opts s) [])
+                      | otherwise = do
+                              pp :: TT (PP p s) <- evalHide @p opts s
+                              case getValueLR opts (msg1 <> " i=" <> showIndex i <> " s=" <> show s) pp [] of
+                                   Left e  -> pure (rs, Left e)
+                                   Right Nothing -> pure (rs, Right ())
+                                   Right w@(Just (_b,s')) -> ff (i+1) s' (rs ++ [((i,w), pp)])
+        (ts,lr) :: ([((Int, PP p s), TT (PP p s))], Either (TT [b]) ()) <- ff 1 q []
+        pure $ case splitAndAlign opts msg1 ts of
+             Left e -> errorInProgram $ "Unfoldr e=" ++ show (fromTT e)
+             Right abcs ->
+               let vals = map (view _1) abcs
+                   itts = map (view _2 &&& view _3) abcs
+               in case lr of
+                   Left e -> mkNode opts (_tBool e) msg1 (hh qq : map (hh . fixit) itts ++ [hh e])
+                   Right () ->
+                     let ret = fst <$> catMaybes vals
+                     in mkNode opts (PresentT ret) (show01' opts msg1 ret "s=" q ) (hh qq : map (hh . fixit) itts)
+
+type family UnfoldT mbs where
+  UnfoldT (Maybe (b,s)) = b
+
+-- | unfolds a value applying \'f\' until the condition \'p\' is true
+--
+-- >>> pl @(IterateUntil (Id < 90) (Pred Id)) 94
+-- Present [94,93,92,91,90] (Unfoldr 94 [94,93,92,91,90] | s=94)
+-- PresentT [94,93,92,91,90]
+--
+data IterateUntil p f
+type IterateUntilT p f = IterateWhile (Not p) f
+
+instance P (IterateUntilT p f) x => P (IterateUntil p f) x where
+  type PP (IterateUntil p f) x = PP (IterateUntilT p f) x
+  eval _ = eval (Proxy @(IterateUntilT p f))
+
+-- | unfolds a value applying \'f\' while the condition \'p\' is true
+--
+-- >>> pl @(IterateWhile (Id > 90) (Pred Id)) 94
+-- Present [94,93,92,91] (Unfoldr 94 [94,93,92,91] | s=94)
+-- PresentT [94,93,92,91]
+--
+data IterateWhile p f
+type IterateWhileT p f = Unfoldr (MaybeBool p '(Id, f)) Id
+
+instance P (IterateWhileT p f) x => P (IterateWhile p f) x where
+  type PP (IterateWhile p f) x = PP (IterateWhileT p f) x
+  eval _ = eval (Proxy @(IterateWhileT p f))
+
+-- | unfolds a value applying \'f\' while the condition \'p\' is true or \'n\' times
+--
+-- >>> pl @(IterateNWhile 10 (Id > 90) (Pred Id)) 95
+-- Present [95,94,93,92,91] ((>>) [95,94,93,92,91] | {Map [95,94,93,92,91] | [(10,95),(9,94),(8,93),(7,92),(6,91)]})
+-- PresentT [95,94,93,92,91]
+--
+-- >>> pl @(IterateNWhile 3 (Id > 90) (Pred Id)) 95
+-- Present [95,94,93] ((>>) [95,94,93] | {Map [95,94,93] | [(3,95),(2,94),(1,93)]})
+-- PresentT [95,94,93]
+--
+data IterateNWhile n p f
+type IterateNWhileT n p f = '(n, Id) >> IterateWhile (Fst Id > 0 && (Snd Id >> p)) (Pred Id *** f) >> Map (Snd Id) Id
+
+instance P (IterateNWhileT n p f) x => P (IterateNWhile n p f) x where
+  type PP (IterateNWhile n p f) x = PP (IterateNWhileT n p f) x
+  eval _ = eval (Proxy @(IterateNWhileT n p f))
+
+-- | unfolds a value applying \'f\' until the condition \'p\' is true or \'n\' times
+--
+-- >>> pl @(IterateNUntil 10 (Id <= 90) (Pred Id)) 95
+-- Present [95,94,93,92,91] ((>>) [95,94,93,92,91] | {Map [95,94,93,92,91] | [(10,95),(9,94),(8,93),(7,92),(6,91)]})
+-- PresentT [95,94,93,92,91]
+--
+-- >>> pl @(IterateNUntil 3 (Id <= 90) (Pred Id)) 95
+-- Present [95,94,93] ((>>) [95,94,93] | {Map [95,94,93] | [(3,95),(2,94),(1,93)]})
+-- PresentT [95,94,93]
+--
+-- >>> pl @(IterateNUntil 9999 'False I) 1
+-- Error Unfoldr (9999,1):recursion limit i=100 ((9999,1) (>>) rhs failed)
+-- FailT "Unfoldr (9999,1):recursion limit i=100"
+--
+data IterateNUntil n p f
+type IterateNUntilT n p f = IterateNWhile n (Not p) f
+
+instance P (IterateNUntilT n p f) x => P (IterateNUntil n p f) x where
+  type PP (IterateNUntil n p f) x = PP (IterateNUntilT n p f) x
+  eval _ = eval (Proxy @(IterateNUntilT n p f))
+
+data ParaImpl (n :: Nat) (os :: [k])
+
+-- | runs values in parallel unlike 'Do' which is serial
+--
+-- >>> pz @(Para '[Id,Id + 1,Id * 4]) [10,20,30]
+-- PresentT [10,21,120]
+--
+-- >>> pz @(Para '[Id,Id + 1,Id * 4]) [10,20,30,40]
+-- FailT "Para:invalid length(4) expected 3"
+--
+-- >>> pl @(Para '[W 'True, Ge 12, W 'False, Lt 2]) [1,2,-99,-999]
+-- Present [True,False,False,True] (Para(0) [True,False,False,True] | [1,2,-99,-999])
+-- PresentT [True,False,False,True]
+--
+-- >>> pl @(Para '[W 'True, Ge 12, W 'False, Lt 2]) [1,2,-99]
+-- Error Para:invalid length(3) expected 4
+-- FailT "Para:invalid length(3) expected 4"
+--
+-- >>> pl @(Para '[W 'True, Ge 12, W 'False, Lt 2]) [1,2,-99,-999,1,1,2]
+-- Error Para:invalid length(7) expected 4
+-- FailT "Para:invalid length(7) expected 4"
+--
+data Para (ps :: [k])
+
+-- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out
+instance ([a] ~ x
+        , GetLen ps
+        , P (ParaImpl (LenT ps) ps) x
+        ) => P (Para ps) x where
+  type PP (Para ps) x = PP (ParaImpl (LenT ps) ps) x
+  eval _ opts as = do
+    let msg0 = "Para"
+        n = getLen @ps
+    if n /= length as then
+       let msg1 = msg0 <> badLength as n
+       in pure $ mkNode opts (FailT msg1) "" []
+    else eval (Proxy @(ParaImpl (LenT ps) ps)) opts as
+
+-- only allow non empty lists -- might need [a] ~ x but it seems fine
+instance GL.TypeError ('GL.Text "ParaImpl '[] invalid: requires at least one value in the list")
+   => P (ParaImpl n ('[] :: [k])) x where
+  type PP (ParaImpl n ('[] :: [k])) x = Void
+  eval _ _ _ = errorInProgram "ParaImpl empty list"
+
+instance (Show (PP p a)
+        , KnownNat n
+        , Show a
+        , P p a
+        ) => P (ParaImpl n '[p]) [a] where
+  type PP (ParaImpl n '[p]) [a] = [PP p a]
+  eval _ opts as' = do
+    let msgbase0 = "Para"
+        msgbase1 = msgbase0 <> "(" <> show n <> ")"
+        n :: Int
+        n = nat @n
+    case as' of
+      [a] -> do
+        pp <- eval (Proxy @p) opts a
+        pure $ case getValueLR opts msgbase1 pp [] of
+          Left e -> e
+          -- showVerbose opts " " [b]  fails but using 'b' is ok and (b : []) also works!
+          -- GE.List problem
+          Right b -> mkNode opts (PresentT [b]) (msgbase1 <> " " <> showL opts [b] <> showVerbose opts " | " a) [hh pp]
+      _ -> errorInProgram $ "ParaImpl base case should have exactly one element but found " ++ show as'
+
+instance (KnownNat n
+        , GetLen ps
+        , P p a
+        , P (ParaImpl n (p1 ': ps)) [a]
+        , PP (ParaImpl n (p1 ': ps)) [a] ~ [PP p a]
+        , Show a
+        , Show (PP p a)
+        )
+     => P (ParaImpl n (p ': p1 ': ps)) [a] where
+  type PP (ParaImpl n (p ': p1 ': ps)) [a] = [PP p a]
+  eval _ opts as' = do
+     let cpos = n-pos-1
+         msgbase0 = msgbase2 <> "(" <> showIndex cpos <> " of " <> show n <> ")"
+         msgbase1 = msgbase2 <> "(" <> showIndex cpos <> ")"
+         msgbase2 = "Para"
+         n = nat @n
+         pos = 1 + getLen @ps -- cos p1!
+     case as' of
+       a:as -> do
+         pp <- eval (Proxy @p) opts a
+         case getValueLR opts msgbase0 pp [] of
+           Left e -> pure e
+           Right b -> do
+                        qq <- eval (Proxy @(ParaImpl n (p1 ': ps))) opts as
+                        pure $ case getValueLR opts (msgbase1 <> " rhs failed " <> show b) qq [hh pp] of
+                          Left e -> e
+                          Right bs -> mkNode opts (PresentT (b:bs)) (msgbase1 <> " " <> showL opts (b:bs) <> showVerbose opts " | " as') [hh pp, hh qq]
+       _ -> errorInProgram "ParaImpl n+1 case has no data left"
+
+-- | leverages 'Para' for repeating expressions (passthrough method)
+--
+-- >>> pz @(ParaN 4 (Succ Id)) [1..4]
+-- PresentT [2,3,4,5]
+--
+-- >>> pz @(ParaN 4 (Succ Id)) "azwxm"
+-- FailT "Para:invalid length(5) expected 4"
+--
+-- >>> pz @(ParaN 4 (Succ Id)) "azwx"
+-- PresentT "b{xy"
+--
+-- >>> pl @(ParaN 5 (Guard "0-255" (Between 0 255 Id))) [1,2,3,4,12]
+-- Present [1,2,3,4,12] (Para(0) [1,2,3,4,12] | [1,2,3,4,12])
+-- PresentT [1,2,3,4,12]
+--
+-- >>> pl @(ParaN 5 (Guard "0-255" (Between 0 255 Id))) [1,2,3,400,12]
+-- Error 0-255 (Para(0) rhs failed 1)
+-- FailT "0-255"
+--
+-- >>> pl @(ParaN 4 (PrintF "%03d" Id)) [141,21,3,0::Int]
+-- Present ["141","021","003","000"] (Para(0) ["141","021","003","000"] | [141,21,3,0])
+-- PresentT ["141","021","003","000"]
+--
+
+data ParaN (n :: Nat) p
+
+instance ( P (ParaImpl (LenT (RepeatT n p)) (RepeatT n p)) x
+         , GetLen (RepeatT n p)
+         , x ~ [a]
+         ) => P (ParaN n p) x where
+  type PP (ParaN n p) x = PP (Para (RepeatT n p)) x
+  eval _ = eval (Proxy @(Para (RepeatT n p)))
+
+-- | creates a promoted list of predicates and then evaluates them into a list. see PP instance for '[k]
+--
+-- >>> pz @(Repeat 4 (Succ Id)) 'c'
+-- PresentT "dddd"
+--
+-- >>> pz @(Repeat 4 "abc") ()
+-- PresentT ["abc","abc","abc","abc"]
+--
+-- >>> pl @(Repeat 4 "xy") 3
+-- Present ["xy","xy","xy","xy"] ('["xy","xy","xy","xy"] ('"xy") | 3)
+-- PresentT ["xy","xy","xy","xy"]
+--
+data Repeat (n :: Nat) p
+instance P (RepeatT n p) a => P (Repeat n p) a where
+  type PP (Repeat n p) a = PP (RepeatT n p) a
+  eval _ = eval (Proxy @(RepeatT n p))
+
+-- | leverages 'Do' for repeating predicates (passthrough method)
+-- same as @DoN n p == FoldN n p Id@ but more efficient
+--
+-- >>> pz @(DoN 4 (Succ Id)) 'c'
+-- PresentT 'g'
+--
+-- >>> pz @(DoN 4 (Id <> " | ")) "abc"
+-- PresentT "abc |  |  |  | "
+--
+-- >>> pz @(DoN 4 (Id <> "|" <> Id)) "abc"
+-- PresentT "abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc"
+--
+-- >>> pl @(DoN 4 (Id + 4)) 1
+-- Present 17 ((>>) 17 | {13 + 4 = 17})
+-- PresentT 17
+--
+-- >>> pl @(DoN 4 (Id + 7)) 3
+-- Present 31 ((>>) 31 | {24 + 7 = 31})
+-- PresentT 31
+--
+-- >>> pl @(DoN 4 9) ()
+-- Present 9 ((>>) 9 | {'9})
+-- PresentT 9
+--
+-- >>> pl @(DoN 4 "xy") 3
+-- Present "xy" ((>>) "xy" | {'"xy"})
+-- PresentT "xy"
+--
+
+data DoN (n :: Nat) p
+type DoNT (n :: Nat) p = Do (RepeatT n p)
+instance P (DoNT n p) a => P (DoN n p) a where
+  type PP (DoN n p) a = PP (DoNT n p) a
+  eval _ = eval (Proxy @(DoNT n p))
+
+ src/Predicate/Data/Json.hs view
@@ -0,0 +1,198 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted json encoding and decoding functions
+-}
+module Predicate.Data.Json (
+
+    ParseJson'
+  , ParseJson
+  , EncodeJson
+  , EncodeJsonFile
+  , ParseJsonFile'
+  , ParseJsonFile
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Data.Proxy
+import Data.Typeable
+import Data.Kind (Type)
+import qualified Data.Aeson as A
+import qualified Data.Aeson.Encode.Pretty as AP
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.ByteString.Lazy.Char8 as BL8
+import System.Directory (doesFileExist)
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+
+-- | parse json data using the type \'t\'
+data ParseJson' t p
+
+instance (P p x
+        , PP p x ~ BL8.ByteString
+        , Typeable (PP t x)
+        , Show (PP t x)
+        , A.FromJSON (PP t x)
+        ) => P (ParseJson' t p) x where
+  type PP (ParseJson' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "ParseJson " <> t
+        t = showT @(PP t x)
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right s ->
+        let hhs = [hh pp]
+            msg1 = msg0 <> "(" ++ litBL opts { oWidth = oWidth opts `div` 3 } s ++ ")"
+        in case A.eitherDecode' s of
+           Right b -> mkNode opts (PresentT b) (msg0 <> " " ++ showL opts { oWidth = oWidth opts `div` 2 } b) hhs
+           Left e -> mkNode opts (FailT (msg1 <> " " <> takeWhile (/=':') e) ) (e <> " | " <> litBL opts s) hhs
+
+-- | parse json data using the type \'t\'
+--
+-- >>> pl @(ParseJson (Int,String) Id) "[10,\"abc\"]"
+-- Present (10,"abc") (ParseJson (Int,[Char]) (10,"abc"))
+-- PresentT (10,"abc")
+--
+-- >>> pl @(ParseJson (Int,String) Id) "[10,\"abc\",99]"
+-- Error ParseJson (Int,[Char])([10,"abc",...) Error in $ (Error in $: cannot unpack array of length 3 into a tuple of length 2 | [10,"abc",99])
+-- FailT "ParseJson (Int,[Char])([10,\"abc\",...) Error in $"
+--
+-- >>> pl @(ParseJson (Int,Bool) (FromString _ Id)) ("[1,true]" :: String)
+-- Present (1,True) (ParseJson (Int,Bool) (1,True))
+-- PresentT (1,True)
+--
+-- >>> pl @(ParseJson (Int,Bool) Id) (A.encode (1,True))
+-- Present (1,True) (ParseJson (Int,Bool) (1,True))
+-- PresentT (1,True)
+--
+-- >>> pl @(ParseJson () Id) "[1,true]"
+-- Error ParseJson ()([1,true]) Error in $ (Error in $: parsing () failed, expected an empty array | [1,true])
+-- FailT "ParseJson ()([1,true]) Error in $"
+--
+data ParseJson (t :: Type) p
+type ParseJsonT (t :: Type) p = ParseJson' (Hole t) p
+
+instance P (ParseJsonT t p) x => P (ParseJson t p) x where
+  type PP (ParseJson t p) x = PP (ParseJsonT t p) x
+  eval _ = eval (Proxy @(ParseJsonT t p))
+
+-- | parse json file \'p\' using the type \'t\'
+data ParseJsonFile' t p
+
+instance (P p x
+        , PP p x ~ String
+        , Typeable (PP t x)
+        , Show (PP t x)
+        , A.FromJSON (PP t x)
+        ) => P (ParseJsonFile' t p) x where
+  type PP (ParseJsonFile' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "ParseJsonFile " <> t
+        t = showT @(PP t x)
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        let hhs = [hh pp]
+            msg1 = msg0 <> "(" <> p <> ")"
+        mb <- runIO $ do
+                b <- doesFileExist p
+                if b then Just <$> BS8.readFile p
+                else pure Nothing
+        pure $ case mb of
+          Nothing -> mkNode opts (FailT msg1) "" hhs
+          Just Nothing -> mkNode opts (FailT (msg1 <> " file does not exist")) "" hhs
+          Just (Just s) ->
+            case A.eitherDecodeStrict' s of
+               Right b -> mkNode opts (PresentT b) (msg1 <> " " ++ showL opts b) hhs
+               Left e -> mkNode opts (FailT (msg1 <> " " <> takeWhile (/=':') e)) (e <> " | " <> litBS opts s) hhs
+
+-- | parse a json file \'p\' using the type \'t\'
+--
+-- >>> pz @(ParseJsonFile [A.Value] "test1.json" >> Id !! 2) ()
+-- PresentT (Object (fromList [("lastName",String "Doe"),("age",Number 45.0),("firstName",String "John"),("likesPizza",Bool False)]))
+--
+data ParseJsonFile (t :: Type) p
+type ParseJsonFileT (t :: Type) p = ParseJsonFile' (Hole t) p
+
+instance P (ParseJsonFileT t p) x => P (ParseJsonFile t p) x where
+  type PP (ParseJsonFile t p) x = PP (ParseJsonFileT t p) x
+  eval _ = eval (Proxy @(ParseJsonFileT t p))
+
+-- | encode json with pretty option
+--
+-- >>> pl @(EncodeJson 'False Id) (10,"def")
+-- Present "[10,\"def\"]" (EncodeJson [10,"def"])
+-- PresentT "[10,\"def\"]"
+--
+-- >>> pl @(EncodeJson 'False Id >> ParseJson (Int,Bool) Id) (1,True)
+-- Present (1,True) ((>>) (1,True) | {ParseJson (Int,Bool) (1,True)})
+-- PresentT (1,True)
+--
+data EncodeJson (pretty :: Bool) p
+
+instance ( GetBool pretty
+         , A.ToJSON (PP p x)
+         , P p x
+         ) => P (EncodeJson pretty p) x where
+  type PP (EncodeJson pretty p) x = BL8.ByteString
+  eval _ opts x = do
+    let msg0 = "EncodeJson"
+        pretty = getBool @pretty
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = (if pretty then AP.encodePretty else A.encode) p
+        in mkNode opts (PresentT d) (msg0 <> " " <> litL opts (litBL opts d)) [hh pp]
+
+-- | encode a json file with pretty option
+data EncodeJsonFile (pretty :: Bool) p q
+
+instance ( GetBool pretty
+         , PP p x ~ String
+         , P p x
+         , A.ToJSON (PP q x)
+         , P q x
+         ) => P (EncodeJsonFile pretty p q) x where
+  type PP (EncodeJsonFile pretty p q) x = ()
+  eval _ opts x = do
+    let msg0 = "EncodeJsonFile"
+        pretty = getBool @pretty
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let d = (if pretty then AP.encodePretty else A.encode) q
+            hhs = [hh pp, hh qq]
+        mb <- runIO $ BL8.writeFile p d
+        pure $ case mb of
+          Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" hhs
+          Just () -> mkNode opts (PresentT ()) (msg0 <> " " <> litL opts (litBL opts d)) hhs
+
+ src/Predicate/Data/List.hs view
@@ -0,0 +1,1885 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE TupleSections #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted list functions
+-}
+module Predicate.Data.List (
+
+ -- ** constructors
+    type (:+)
+  , type (+:)
+  , type (++)
+  , Singleton
+  , EmptyT
+  , EmptyList
+  , EmptyList'
+
+ -- ** destructors
+  , Uncons
+  , Unsnoc
+  , Head
+  , Tail
+  , Init
+  , Last
+
+ -- ** sort
+  , SortBy
+  , SortOn
+  , SortOnDesc
+
+ -- ** zip related
+  , Unzip
+  , Unzip3
+  , ZipL
+  , ZipR
+  , Zip
+  , ZipWith
+
+ -- ** higher order methods
+  , Partition
+  , PartitionBy
+  , GroupBy
+  , Filter
+  , Break
+  , Span
+  , Intercalate
+
+ -- ** miscellaneous
+  , Len
+  , Length
+  , Elem
+  , Inits
+  , Tails
+  , Ones
+  , PadL
+  , PadR
+  , SplitAts
+  , SplitAt
+  , ChunksOf
+  , Rotate
+  , Take
+  , Drop
+  , Remove
+  , Keep
+  , Reverse
+  , ReverseL
+
+  , Sum
+  , Product
+  , Min
+  , Max
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Ordering (type (==), OrdA)
+import Predicate.Data.Numeric (Mod)
+import Predicate.Data.Monoid (type (<>))
+import Control.Lens hiding (iall)
+import Data.List
+import Data.Proxy
+import Control.Monad
+import Data.Kind (Type)
+import Data.Foldable (toList)
+import Control.Arrow
+import qualified Data.Sequence as Seq
+import Data.Bool
+import qualified Data.Map.Strict as M
+import Control.Applicative
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Map.Strict as M
+-- >>> import qualified Data.Text as T
+-- >>> import Data.These
+-- >>> import Predicate.Prelude
+
+-- | similar to (++)
+--
+-- >>> pz @(Fst Id ++ Snd Id) ([9,10,11],[1,2,3,4])
+-- PresentT [9,10,11,1,2,3,4]
+--
+-- >>> pz @(Snd Id ++ Fst Id) ([],[5])
+-- PresentT [5]
+--
+-- >>> pz @(Char1 "xyz" :+ W "ab" ++ W "cdefg") ()
+-- PresentT "xabcdefg"
+--
+-- >>> pz @([1,2,3] ++ EmptyList _) "somestuff"
+-- PresentT [1,2,3]
+--
+data p ++ q
+infixr 5 ++
+
+instance (P p x
+        , P q x
+        , Show (PP p x)
+        , PP p x ~ [a]
+        , PP q x ~ [a]
+        ) => P (p ++ q) x where
+  type PP (p ++ q) x = PP q x
+  eval _ opts z = do
+    let msg0 = "(++)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = p ++ q
+        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+
+
+-- cant directly create a singleton type using '[] since the type of '[] is unknown. instead use 'Singleton' or 'EmptyT'
+
+-- | similar to cons
+--
+-- >>> pz @(Fst Id :+ Snd Id) (99,[1,2,3,4])
+-- PresentT [99,1,2,3,4]
+--
+-- >>> pz @(Snd Id :+ Fst Id) ([],5)
+-- PresentT [5]
+--
+-- >>> pz @(123 :+ EmptyList _) "somestuff"
+-- PresentT [123]
+--
+-- >>> pl @(FlipT (:+) (Fst Id) (Snd Id)) ([1..5],99)
+-- Present [99,1,2,3,4,5] ((:+) [99,1,2,3,4,5] | p=99 | q=[1,2,3,4,5])
+-- PresentT [99,1,2,3,4,5]
+--
+-- >>> pl @(Fst Id :+ Snd Id) (99,[1..5])
+-- Present [99,1,2,3,4,5] ((:+) [99,1,2,3,4,5] | p=99 | q=[1,2,3,4,5])
+-- PresentT [99,1,2,3,4,5]
+--
+-- >>> pl @(4 :+ '[1,2,3]) ()
+-- Present [4,1,2,3] ((:+) [4,1,2,3] | p=4 | q=[1,2,3])
+-- PresentT [4,1,2,3]
+--
+-- >>> pl @(Fst Id :+ Snd Id) (4,[1,2,3])
+-- Present [4,1,2,3] ((:+) [4,1,2,3] | p=4 | q=[1,2,3])
+-- PresentT [4,1,2,3]
+--
+-- >>> pl @(FlipT (:+) '[1,2,3] 5) ()
+-- Present [5,1,2,3] ((:+) [5,1,2,3] | p=5 | q=[1,2,3])
+-- PresentT [5,1,2,3]
+--
+data p :+ q
+infixr 5 :+
+
+instance (P p x
+        , P q x
+        , Show (PP p x)
+        , Show (PP q x)
+        , Cons (PP q x) (PP q x) (PP p x) (PP p x)
+        ) => P (p :+ q) x where
+  type PP (p :+ q) x = PP q x
+  eval _ opts z = do
+    let msg0 = "(:+)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = p `cons` q
+        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | similar to snoc
+--
+-- >>> pz @(Snd Id +: Fst Id) (99,[1,2,3,4])
+-- PresentT [1,2,3,4,99]
+--
+-- >>> pz @(Fst Id +: Snd Id) ([],5)
+-- PresentT [5]
+--
+-- >>> pz @(EmptyT [] Id +: 5) 5
+-- PresentT [5]
+--
+-- >>> pl @('[1,2,3] +: 4) ()
+-- Present [1,2,3,4] ((+:) [1,2,3,4] | p=[1,2,3] | q=4)
+-- PresentT [1,2,3,4]
+--
+-- >>> pl @(Snd Id +: Fst Id) (4,[1,2,3])
+-- Present [1,2,3,4] ((+:) [1,2,3,4] | p=[1,2,3] | q=4)
+-- PresentT [1,2,3,4]
+--
+-- >>> pl @("abc" +: Char1 "x") ()
+-- Present "abcx" ((+:) "abcx" | p="abc" | q='x')
+-- PresentT "abcx"
+--
+-- >>> pl @(Fst Id +: Snd Id) ("abc" :: T.Text,'x')
+-- Present "abcx" ((+:) "abcx" | p="abc" | q='x')
+-- PresentT "abcx"
+--
+data p +: q
+infixl 5 +:
+
+instance (P p x
+        , P q x
+        , Show (PP q x)
+        , Show (PP p x)
+        , Snoc (PP p x) (PP p x) (PP q x) (PP q x)
+        ) => P (p +: q) x where
+  type PP (p +: q) x = PP p x
+  eval _ opts z = do
+    let msg0 = "(+:)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = p `snoc` q
+        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | similar to 'Control.Lens.uncons'
+--
+-- >>> pz @Uncons [1,2,3,4]
+-- PresentT (Just (1,[2,3,4]))
+--
+-- >>> pz @Uncons []
+-- PresentT Nothing
+--
+-- >>> pz @Uncons (Seq.fromList "abc")
+-- PresentT (Just ('a',fromList "bc"))
+--
+-- >>> pz @Uncons ("xyz" :: T.Text)
+-- PresentT (Just ('x',"yz"))
+--
+-- >>> pl @Uncons ("asfd" :: T.Text)
+-- Present Just ('a',"sfd") (Uncons Just ('a',"sfd") | "asfd")
+-- PresentT (Just ('a',"sfd"))
+--
+-- >>> pl @Uncons ("" :: T.Text)
+-- Present Nothing (Uncons Nothing | "")
+-- PresentT Nothing
+--
+-- >>> pl @Uncons [1..5] -- with Typeable would need to specify the type of [1..5]
+-- Present Just (1,[2,3,4,5]) (Uncons Just (1,[2,3,4,5]) | [1,2,3,4,5])
+-- PresentT (Just (1,[2,3,4,5]))
+--
+
+data Uncons
+
+instance (Show (ConsT s)
+        , Show s
+        , Cons s s (ConsT s) (ConsT s)
+        ) => P Uncons s where
+  type PP Uncons s = Maybe (ConsT s,s)
+  eval _ opts as =
+    let msg0 = "Uncons"
+        b = as ^? _Cons
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | similar to 'Control.Lens.unsnoc'
+--
+-- >>> pz @Unsnoc [1,2,3,4]
+-- PresentT (Just ([1,2,3],4))
+--
+-- >>> pz @Unsnoc []
+-- PresentT Nothing
+--
+-- >>> pz @Unsnoc ("xyz" :: T.Text)
+-- PresentT (Just ("xy",'z'))
+--
+-- >>> pl @Unsnoc ("asfd" :: T.Text)
+-- Present Just ("asf",'d') (Unsnoc Just ("asf",'d') | "asfd")
+-- PresentT (Just ("asf",'d'))
+--
+-- >>> pl @Unsnoc ("" :: T.Text)
+-- Present Nothing (Unsnoc Nothing | "")
+-- PresentT Nothing
+--
+-- >>> pl @Unsnoc [1..5]
+-- Present Just ([1,2,3,4],5) (Unsnoc Just ([1,2,3,4],5) | [1,2,3,4,5])
+-- PresentT (Just ([1,2,3,4],5))
+--
+
+data Unsnoc
+
+instance (Show (ConsT s)
+        , Show s
+        , Snoc s s (ConsT s) (ConsT s)
+        ) => P Unsnoc s where
+  type PP Unsnoc s = Maybe (s,ConsT s)
+  eval _ opts as =
+    let msg0 = "Unsnoc"
+        b = as ^? _Snoc
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | rotate a list \'p\' \'n\' units
+--
+-- >>> pz @(Rotate 0 Id) [1,2,3,4]
+-- PresentT [1,2,3,4]
+--
+-- >>> pz @(Rotate (Negate 1) Id) [1,2,3,4]
+-- PresentT [4,1,2,3]
+--
+-- >>> pz @(Rotate 2 Id) [1,2,3,4]
+-- PresentT [3,4,1,2]
+--
+-- >>> pz @(Map (Rotate Id "abcd") Id) [-3..7]
+-- PresentT ["bcda","cdab","dabc","abcd","bcda","cdab","dabc","abcd","bcda","cdab","dabc"]
+--
+data Rotate n p
+type RotateT n p = SplitAt (n `Mod` Length p) p >> Swap >> Fst Id <> Snd Id
+
+instance P (RotateT n p) x => P (Rotate n p) x where
+  type PP (Rotate n p) x = PP (RotateT n p) x
+  eval _ = eval (Proxy @(RotateT n p))
+
+
+-- | similar to 'partition'
+--
+-- >>> pz @(Partition (Ge 3) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([10,4,7,3,3,5],[1,1])
+--
+-- >>> pz @(Partition (Prime Id) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([7,3,3,5],[10,4,1,1])
+--
+-- >>> pz @(Partition (Ge 300) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([],[10,4,1,7,3,1,3,5])
+--
+-- >>> pz @(Partition (Id < 300) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([10,4,1,7,3,1,3,5],[])
+--
+-- >>> pl @(Partition (Lt 2) Id >> Id) [1,2,3,4,5]
+-- Present ([1],[2,3,4,5]) ((>>) ([1],[2,3,4,5]) | {Id ([1],[2,3,4,5])})
+-- PresentT ([1],[2,3,4,5])
+--
+-- >>> pl @(Partition (Gt 3) Id) [1..10]
+-- Present ([4,5,6,7,8,9,10],[1,2,3]) (Partition ([4,5,6,7,8,9,10],[1,2,3]) | s=[1,2,3,4,5,6,7,8,9,10])
+-- PresentT ([4,5,6,7,8,9,10],[1,2,3])
+--
+-- >>> pl @(Partition Even Id) [1..6]
+-- Present ([2,4,6],[1,3,5]) (Partition ([2,4,6],[1,3,5]) | s=[1,2,3,4,5,6])
+-- PresentT ([2,4,6],[1,3,5])
+--
+-- >>> pl @(Partition Even Id >> Null *** (Len > 4) >> Fst Id == Snd Id) [1..6]
+-- True ((>>) True | {False == False})
+-- TrueT
+--
+-- >>> pl @(Partition (ExitWhen "ExitWhen" (Gt 10) >> Gt 2) Id) [1..11]
+-- Error ExitWhen (Partition(i=10, a=11) excnt=1)
+-- FailT "ExitWhen"
+--
+-- >>> pl @(Partition (Prime Id) Id) [1..15]
+-- Present ([2,3,5,7,11,13],[1,4,6,8,9,10,12,14,15]) (Partition ([2,3,5,7,11,13],[1,4,6,8,9,10,12,14,15]) | s=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])
+-- PresentT ([2,3,5,7,11,13],[1,4,6,8,9,10,12,14,15])
+--
+data Partition p q
+
+instance (P p x
+        , Show x
+        , PP q a ~ [x]
+        , PP p x ~ Bool
+        , P q a
+        ) => P (Partition p q) a where
+  type PP (Partition p q) a = (PP q a, PP q a)
+  eval _ opts a' = do
+    let msg0 = "Partition"
+    qq <- eval (Proxy @q) opts a'
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () -> do
+             ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide @p opts a) [0::Int ..] q
+             pure $ case splitAndAlign opts msg0 ts of
+               Left e -> e
+               Right abcs ->
+                 let itts = map (view _2 &&& view _3) abcs
+                     w0 = partition (view _1) abcs
+                     zz1 = (map (view (_2 . _2)) *** map (view (_2 . _2))) w0
+                 in mkNode opts (PresentT zz1) (show01' opts msg0 zz1 "s=" q) (hh qq : map (hh . fixit) itts)
+
+
+-- | partition values based on a function
+--
+-- >>> pz @(PartitionBy Ordering (Case 'EQ '[Id < 0, Id > 0] '[ 'LT, 'GT] Id) Id) [-4,-2,5,6,7,0,-1,2,-3,4,0]
+-- PresentT (fromList [(LT,[-3,-1,-2,-4]),(EQ,[0,0]),(GT,[4,2,7,6,5])])
+--
+-- >>> pl @(PartitionBy Ordering (Case (Failt _ "asdf") '[Id < 2, Id == 2, Id > 2] '[ 'LT, 'EQ, 'GT] Id) Id) [-4,2,5,6,7,1,2,3,4]
+-- Present fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])] (PartitionBy fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])] | s=[-4,2,5,6,7,1,2,3,4])
+-- PresentT (fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])])
+--
+-- >>> pl @(PartitionBy Ordering (Case (Failt _ "xyzxyzxyzzyyysyfsyfydf") '[Id < 2, Id == 2, Id > 3] '[ 'LT, 'EQ, 'GT] Id) Id) [-4,2,5,6,7,1,2,3,4]
+-- Error xyzxyzxyzzyyysyfsyfydf (PartitionBy(i=7, a=3) excnt=1)
+-- FailT "xyzxyzxyzzyyysyfsyfydf"
+--
+data PartitionBy t p q
+
+instance (P p x
+        , Ord t
+        , Show x
+        , Show t
+        , PP q a ~ [x]
+        , PP p x ~ t
+        , P q a
+        ) => P (PartitionBy t p q) a where
+  type PP (PartitionBy t p q) a = M.Map t (PP q a)
+  eval _ opts a' = do
+    let msg0 = "PartitionBy"
+    qq <- eval (Proxy @q) opts a'
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () -> do
+             ts <- zipWithM (\i a -> ((i, a),) <$> evalHide @p opts a) [0::Int ..] q
+             pure $ case splitAndAlign opts msg0 ts of
+                   Left e -> e
+                   Right abcs ->
+                     let kvs = map (view _1 &&& ((:[]) . view (_2 . _2))) abcs
+                         itts = map (view _2 &&& view _3) abcs
+                         ret = M.fromListWith (++) kvs
+                     in mkNode opts (PresentT ret) (show01' opts msg0 ret "s=" q ) (hh qq : map (hh . fixit) itts)
+
+-- | similar to 'groupBy'
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,3,4,5,1,5,5]
+-- PresentT [[1],[3],[4],[5],[1],[5,5]]
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,1,1,3,4,5,1,5,5]
+-- PresentT [[1,1,1],[3],[4],[5],[1],[5,5]]
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [5,5]
+-- PresentT [[5,5]]
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,2]
+-- PresentT [[1],[2]]
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1]
+-- PresentT [[1]]
+--
+-- >>> pz @(GroupBy (Fst Id == Snd Id) Id) []
+-- PresentT []
+--
+-- >>> pz @(GroupBy (Fst Id < Snd Id) Id) [1,2,3,4,4,1,2]
+-- PresentT [[1,2,3,4],[4],[1,2]]
+--
+-- >>> pz @(GroupBy (Fst Id /= Snd Id) Id) [1,2,3,4,4,4,1]
+-- PresentT [[1,2,3,4],[4],[4,1]]
+--
+-- >>> pan @(GroupBy (Fst Id == Snd Id) Id) "hello    goodbye"
+-- P GroupBy ["h","e","ll","o","    ","g","oo","d","b","y","e"]
+-- |
+-- +- P Id "hello    goodbye"
+-- |
+-- +- False i=0: 'h' == 'e'
+-- |
+-- +- False i=1: 'e' == 'l'
+-- |
+-- +- True i=2: 'l' == 'l'
+-- |
+-- +- False i=3: 'l' == 'o'
+-- |
+-- +- False i=4: 'o' == ' '
+-- |
+-- +- True i=5: ' ' == ' '
+-- |
+-- +- True i=6: ' ' == ' '
+-- |
+-- +- True i=7: ' ' == ' '
+-- |
+-- +- False i=8: ' ' == 'g'
+-- |
+-- +- False i=9: 'g' == 'o'
+-- |
+-- +- True i=10: 'o' == 'o'
+-- |
+-- +- False i=11: 'o' == 'd'
+-- |
+-- +- False i=12: 'd' == 'b'
+-- |
+-- +- False i=13: 'b' == 'y'
+-- |
+-- `- False i=14: 'y' == 'e'
+-- PresentT ["h","e","ll","o","    ","g","oo","d","b","y","e"]
+--
+data GroupBy p q
+
+instance (Show x
+        , PP q a ~ [x]
+        , PP p (x,x) ~ Bool
+        , P p (x,x)
+        , P q a
+        ) => P (GroupBy p q) a where
+  type PP (GroupBy p q) a = [PP q a]
+  eval _ opts a' = do
+    let msg0 = "GroupBy"
+    qq <- eval (Proxy @q) opts a'
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () ->
+             case q of
+               [] -> pure $ mkNode opts (PresentT []) (show01' opts msg0 q "s=" q) [hh qq]
+               [_] -> pure $ mkNode opts (PresentT [q]) (show01' opts msg0 [q] "s=" q) [hh qq]
+               x:xs -> do
+                 ts <- zipWithM (\i (a,b) -> ((i, b),) <$> evalBoolHide @p opts (a,b)) [0::Int ..] (zip (x:xs) xs)
+                 pure $ case splitAndAlign opts msg0 ts of
+                   Left e -> e
+                   Right abcs ->
+                     let ret = gp1 x abcs
+                         itts = map (view _2 &&& view _3) abcs
+                     in mkNode opts (PresentT ret) (show01' opts msg0 ret "s=" q ) (hh qq : map (hh . fixit) itts)
+
+gp1 :: x -> [(Bool, (Int, x), TT Bool)] -> [[x]]
+gp1 b = go [b]
+  where
+  go ret =
+     \case
+       [] -> [ret]
+       (tf, (_, a), _):as -> if tf then go (ret <> [a]) as
+                             else ret : go [a] as
+
+data Filter p q
+type FilterT p q = Fst (Partition p q)
+
+instance P (FilterT p q) x => P (Filter p q) x where
+  type PP (Filter p q) x = PP (FilterT p q) x
+  eval _ = eval (Proxy @(FilterT p q))
+
+-- | similar to 'break'
+--
+-- >>> pz @(Break (Ge 3) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([],[10,4,1,7,3,1,3,5])
+--
+-- >>> pz @(Break (Lt 3) Id) [10,4,1,7,3,1,3,5]
+-- PresentT ([10,4],[1,7,3,1,3,5])
+--
+-- >>> pl @(Break (Gt 2) Id) [1..11]
+-- Present ([1,2],[3,4,5,6,7,8,9,10,11]) (Break cnt=(2,9))
+-- PresentT ([1,2],[3,4,5,6,7,8,9,10,11])
+--
+-- >>> pl @(Break (If (Gt 2) 'True (If (Gt 4) (Failt _ "ASfd") 'False)) Id) [1..8]
+-- Present ([1,2],[3,4,5,6,7,8]) (Break cnt=(2,6))
+-- PresentT ([1,2],[3,4,5,6,7,8])
+--
+-- >>> pl @(Break (Case 'False '[Gt 2,Gt 4] '[ W 'True, Failt _ "ASfd"] Id) Id) [1..8]  -- case version
+-- Present ([1,2],[3,4,5,6,7,8]) (Break cnt=(2,6))
+-- PresentT ([1,2],[3,4,5,6,7,8])
+--
+-- >>> pl @(Break (If (Gt 2) (Failt _ "ASfd") 'False) Id) [1..8]
+-- Error ASfd (Break predicate failed)
+-- FailT "ASfd"
+--
+-- >>> pl @(Break (Snd Id) Id) (zip [1..] [False,False,False,True,True,False])
+-- Present ([(1,False),(2,False),(3,False)],[(4,True),(5,True),(6,False)]) (Break cnt=(3,3))
+-- PresentT ([(1,False),(2,False),(3,False)],[(4,True),(5,True),(6,False)])
+--
+-- >>> pl @(Break (Snd Id) Id) (zip [1..] [False,False,False,False])
+-- Present ([(1,False),(2,False),(3,False),(4,False)],[]) (Break cnt=(4,0))
+-- PresentT ([(1,False),(2,False),(3,False),(4,False)],[])
+--
+-- >>> pl @(Break (Snd Id) Id) (zip [1..] [True,True,True,True])
+-- Present ([],[(1,True),(2,True),(3,True),(4,True)]) (Break cnt=(0,4))
+-- PresentT ([],[(1,True),(2,True),(3,True),(4,True)])
+--
+
+data Break p q
+
+-- only process up to the pivot! only process while Right False
+-- a predicate can return PresentP not just TrueP
+instance (P p x
+        , PP q a ~ [x]
+        , PP p x ~ Bool
+        , P q a
+        ) => P (Break p q) a where
+  type PP (Break p q) a = (PP q a, PP q a)
+  eval _ opts a' = do
+    let msg0 = "Break"
+    qq <- eval (Proxy @q) opts a'
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case chkSize opts msg0 q [hh qq] of
+          Left e -> pure e
+          Right () -> do
+            let ff [] zs = pure (zs, [], Nothing) -- [(ia,qq)] extras | the rest of the data | optional last pivot or failure
+                ff ((i,a):ias) zs = do
+                   pp <- evalBoolHide @p opts a
+                   let v = ((i,a), pp)
+                   case getValueLR opts msg0 pp [hh qq] of
+                     Right False -> ff ias (zs Seq.|> v)
+                     Right True -> pure (zs,map snd ias,Just v)
+                     Left _ -> pure (zs,map snd ias,Just v)
+            (ialls,rhs,mpivot) <- ff (itoList q) Seq.empty
+            pure $ case mpivot of
+                 Nothing ->
+                   mkNode opts (PresentT (map (snd . fst) (toList ialls), rhs))
+                           (msg0 <> " cnt=" <> show (length ialls, length rhs))
+                           (map (hh . fixit) (toList ialls))
+                 Just iall@(ia, tt) ->
+                   case getValueLR opts (msg0 <> " predicate failed") tt (hh qq : map (hh . fixit) (toList (ialls Seq.|> iall))) of
+                     Right True ->
+                       mkNode opts (PresentT (map (snd . fst) (toList ialls), snd ia : rhs))
+                               (msg0 <> " cnt=" <> show (length ialls, 1+length rhs))
+                               (hh qq : hh tt : map (hh . fixit) (toList (ialls Seq.|> iall)))
+
+                     Right False -> errorInProgram "Break"
+                     Left e -> e
+
+-- | similar to 'span'
+--
+-- >>> pl @(Span (Lt 4) Id) [1..11]
+-- Present ([1,2,3],[4,5,6,7,8,9,10,11]) (Break cnt=(3,8))
+-- PresentT ([1,2,3],[4,5,6,7,8,9,10,11])
+--
+
+data Span p q
+type SpanT p q = Break (Not p) q
+
+instance P (SpanT p q) x => P (Span p q) x where
+  type PP (Span p q) x = PP (SpanT p q) x
+  eval _ = eval (Proxy @(SpanT p q))
+
+-- | intercalate two lists
+--
+-- >>> pz @(Intercalate '["aB"] '["xxxx","yz","z","www","xyz"]) ()
+-- PresentT ["xxxx","aB","yz","aB","z","aB","www","aB","xyz"]
+--
+-- >>> pz @(Intercalate '[W 99,Negate 98] Id) [1..5]
+-- PresentT [1,99,-98,2,99,-98,3,99,-98,4,99,-98,5]
+--
+-- >>> pz @(Intercalate '[99,100] Id) [1..5]
+--PresentT [1,99,100,2,99,100,3,99,100,4,99,100,5]
+--
+-- >>> pl @(Intercalate (Fst Id) (Snd Id)) ([0,1], [12,13,14,15,16])
+-- Present [12,0,1,13,0,1,14,0,1,15,0,1,16] (Intercalate [12,0,1,13,0,1,14,0,1,15,0,1,16] | [0,1] | [12,13,14,15,16])
+-- PresentT [12,0,1,13,0,1,14,0,1,15,0,1,16]
+--
+-- >>> pl @((Pure [] (Negate Len) &&& Id) >> Intercalate (Fst Id) (Snd Id)) [12,13,14,15,16]
+-- Present [12,-5,13,-5,14,-5,15,-5,16] ((>>) [12,-5,13,-5,14,-5,15,-5,16] | {Intercalate [12,-5,13,-5,14,-5,15,-5,16] | [-5] | [12,13,14,15,16]})
+-- PresentT [12,-5,13,-5,14,-5,15,-5,16]
+--
+data Intercalate p q
+
+instance (PP p x ~ [a]
+        , PP q x ~ PP p x
+        , P p x
+        , P q x
+        , Show a
+      ) => P (Intercalate p q) x where
+  type PP (Intercalate p q) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Intercalate"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> e
+          Right () ->
+            let d = intercalate p (map pure q)
+            in mkNode opts (PresentT d) (show01 opts msg0 d p <> showVerbose opts " | " q) hhs
+
+-- | 'elem' function
+--
+-- >>> pz @(Elem (Fst Id) (Snd Id)) ('x',"abcdxy")
+-- TrueT
+--
+-- >>> pz @(Elem (Fst Id) (Snd Id)) ('z',"abcdxy")
+-- FalseT
+--
+-- >>> pl @(Elem Id '[2,3,4]) 2
+-- True (2 `elem` [2,3,4])
+-- TrueT
+--
+-- >>> pl @(Elem Id '[2,3,4]) 6
+-- False (6 `elem` [2,3,4])
+-- FalseT
+--
+-- >>> pl @(Elem Id '[13 % 2]) 6.5
+-- True (13 % 2 `elem` [13 % 2])
+-- TrueT
+--
+-- >>> pl @(Elem Id '[13 % 2, 12 % 1]) 6.5
+-- True (13 % 2 `elem` [13 % 2,12 % 1])
+-- TrueT
+--
+-- >>> pl @(Elem Id '[13 % 2, 12 % 1]) 6
+-- False (6 % 1 `elem` [13 % 2,12 % 1])
+-- FalseT
+--
+
+data Elem p q
+
+instance ([PP p a] ~ PP q a
+         , P p a
+         , P q a
+         , Show (PP p a)
+         , Eq (PP p a)
+         ) => P (Elem p q) a where
+  type PP (Elem p q) a = Bool
+  eval _ opts a = do
+    let msg0 = "Elem"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = p `elem` q
+        in mkNodeB opts b (showL opts p <> " `elem` " <> showL opts q) [hh pp, hh qq]
+
+-- | similar to 'Data.List.inits'
+--
+-- >>> pz @Inits [4,8,3,9]
+-- PresentT [[],[4],[4,8],[4,8,3],[4,8,3,9]]
+--
+-- >>> pz @Inits []
+-- PresentT [[]]
+--
+data Inits
+
+instance ( [a] ~ x
+         , Show a
+         ) => P Inits x where
+  type PP Inits x = [x]
+  eval _ opts as =
+    let msg0 = "Inits"
+        xs = inits as
+    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
+
+-- | similar to 'Data.List.tails'
+--
+-- >>> pz @Tails [4,8,3,9]
+-- PresentT [[4,8,3,9],[8,3,9],[3,9],[9],[]]
+--
+-- >>> pz @Tails []
+-- PresentT [[]]
+--
+-- >>> pl @Tails "abcd"
+-- Present ["abcd","bcd","cd","d",""] (Tails ["abcd","bcd","cd","d",""] | "abcd")
+-- PresentT ["abcd","bcd","cd","d",""]
+--
+data Tails
+
+instance ( [a] ~ x
+         , Show a
+         ) => P Tails x where
+  type PP Tails x = [x]
+  eval _ opts as =
+    let msg0 = "Tails"
+        xs = tails as
+    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
+
+-- | split a list into single values
+--
+-- >>> pz @(Ones Id) [4,8,3,9]
+-- PresentT [[4],[8],[3],[9]]
+--
+-- >>> pz @(Ones Id) []
+-- PresentT []
+--
+data Ones p
+
+instance ( PP p x ~ [a]
+         , P p x
+         , Show a
+         ) => P (Ones p) x where
+  type PP (Ones p) x = [PP p x]
+  eval _ opts x = do
+    let msg0 = "Ones"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case chkSize opts msg0 p [hh pp] of
+          Left e -> e
+          Right () ->
+            let d = map pure p
+            in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+data PadImpl (left :: Bool) n p q
+
+instance (P n a
+        , GetBool left
+        , Integral (PP n a)
+        , [PP p a] ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        ) => P (PadImpl left n p q) a where
+  type PP (PadImpl left n p q) a = PP q a
+  eval _ opts a = do
+    let msg0 = "Pad" <> (if lft then "L" else "R")
+        lft = getBool @left
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
+    case lr of
+      Left e -> pure e
+      Right (fromIntegral -> n,p,nn,pp) -> do
+        let msg1 = msg0 <> " " <> showL opts n <> " pad=" <> show p
+            hhs = [hh nn, hh pp]
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts (msg1 <> " q failed") qq hhs of
+          Left e -> e
+          Right q ->
+            let l = length q
+                diff = if n<=l then 0 else n-l
+                bs = if lft
+                     then replicate diff p <> q
+                     else q <> replicate diff p
+            in mkNode opts (PresentT bs) (show01 opts msg1 bs q) (hhs <> [hh qq])
+
+-- | left pad \'q\' with \'n\' values from \'p\'
+--
+-- >>> pl @(PadL 5 0 Id) [1..3]
+-- Present [0,0,1,2,3] (PadL 5 pad=0 [0,0,1,2,3] | [1,2,3])
+-- PresentT [0,0,1,2,3]
+--
+-- >>> pz @(PadL 5 999 Id) [12,13]
+-- PresentT [999,999,999,12,13]
+--
+-- >>> pz @(PadR 5 (Fst Id) '[12,13]) (999,'x')
+-- PresentT [12,13,999,999,999]
+--
+-- >>> pz @(PadR 2 (Fst Id) '[12,13,14]) (999,'x')
+-- PresentT [12,13,14]
+--
+-- >>> pl @(PadL 10 0 Id) [1..3]
+-- Present [0,0,0,0,0,0,0,1,2,3] (PadL 10 pad=0 [0,0,0,0,0,0,0,1,2,3] | [1,2,3])
+-- PresentT [0,0,0,0,0,0,0,1,2,3]
+--
+data PadL n p q
+type PadLT n p q = PadImpl 'True n p q
+
+instance P (PadLT n p q) x => P (PadL n p q) x where
+  type PP (PadL n p q) x = PP (PadLT n p q) x
+  eval _ = eval (Proxy @(PadLT n p q))
+
+-- | right pad \'q\' with \'n\' values from \'p\'
+--
+-- >>> pl @(PadR 5 8 Id) [1..3]
+-- Present [1,2,3,8,8] (PadR 5 pad=8 [1,2,3,8,8] | [1,2,3])
+-- PresentT [1,2,3,8,8]
+--
+-- >>> pl @(PadR 5 0 Id) [1..5]
+-- Present [1,2,3,4,5] (PadR 5 pad=0 [1,2,3,4,5] | [1,2,3,4,5])
+-- PresentT [1,2,3,4,5]
+--
+-- >>> pl @(PadR 5 0 Id) [1..6]
+-- Present [1,2,3,4,5,6] (PadR 5 pad=0 [1,2,3,4,5,6] | [1,2,3,4,5,6])
+-- PresentT [1,2,3,4,5,6]
+--
+data PadR n p q
+type PadRT n p q = PadImpl 'False n p q
+
+instance P (PadRT n p q) x => P (PadR n p q) x where
+  type PP (PadR n p q) x = PP (PadRT n p q) x
+  eval _ = eval (Proxy @(PadRT n p q))
+
+-- | split a list \'p\' into parts using the lengths in the type level list \'ns\'
+--
+-- >>> pz @(SplitAts '[2,3,1,1] Id) "hello world"
+-- PresentT ["he","llo"," ","w","orld"]
+--
+-- >>> pz @(SplitAts '[2] Id) "hello world"
+-- PresentT ["he","llo world"]
+--
+-- >>> pz @(SplitAts '[10,1,1,5] Id) "hello world"
+-- PresentT ["hello worl","d","",""]
+--
+-- >>> pl @(SplitAts '[1,3,4] Id) [1..12]
+-- Present [[1],[2,3,4],[5,6,7,8],[9,10,11,12]] (SplitAts [[1],[2,3,4],[5,6,7,8],[9,10,11,12]] | ns=[1,3,4] | [1,2,3,4,5,6,7,8,9,10,11,12])
+-- PresentT [[1],[2,3,4],[5,6,7,8],[9,10,11,12]]
+--
+-- >>> pl @(SplitAts '[3,1,1,1] Id >> Filter (Not Null) Id) [1..4]
+-- Present [[1,2,3],[4]] ((>>) [[1,2,3],[4]] | {Fst [[1,2,3],[4]] | ([[1,2,3],[4]],[[],[]])})
+-- PresentT [[1,2,3],[4]]
+--
+data SplitAts ns p
+
+instance (P ns x
+        , P p x
+        , PP p x ~ [a]
+        , Show n
+        , Show a
+        , PP ns x ~ [n]
+        , Integral n
+        ) => P (SplitAts ns p) x where
+  type PP (SplitAts ns p) x = [PP p x]
+  eval _ opts x = do
+    let msg0 = "SplitAts"
+    lr <- runPQ msg0 (Proxy @ns) (Proxy @p) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (ns,p,nn,pp) ->
+        let zs = foldr (\n k s -> let (a,b) = splitAtNeg (fromIntegral n) s
+                              in a:k b
+                   ) (\as -> if null as then [] else [as]) ns p
+        in mkNode opts (PresentT zs) (show01' opts msg0 zs "ns=" ns <> showVerbose opts " | " p) [hh nn, hh pp]
+
+-- | similar to 'splitAt'
+--
+-- >>> pz @(SplitAt 4 Id) "hello world"
+-- PresentT ("hell","o world")
+--
+-- >>> pz @(SplitAt 20 Id) "hello world"
+-- PresentT ("hello world","")
+--
+-- >>> pz @(SplitAt 0 Id) "hello world"
+-- PresentT ("","hello world")
+--
+-- >>> pz @(SplitAt (Snd Id) (Fst Id)) ("hello world",4)
+-- PresentT ("hell","o world")
+--
+-- >>> pz @(SplitAt (Negate 2) Id) "hello world"
+-- PresentT ("hello wor","ld")
+--
+-- >>> pl @(Snd Id >> SplitAt 2 Id >> Len *** Len >> Fst Id > Snd Id) ('x',[1..5])
+-- False ((>>) False | {2 > 3})
+-- FalseT
+--
+data SplitAt n p
+
+instance (PP p a ~ [b]
+        , P n a
+        , P p a
+        , Show b
+        , Integral (PP n a)
+        ) => P (SplitAt n p) a where
+  type PP (SplitAt n p) a = (PP p a, PP p a)
+  eval _ opts a = do
+    let msg0 = "SplitAt"
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
+    pure $ case lr of
+      Left e -> e -- (Left e, tt')
+      Right (fromIntegral -> n,p,pp,qq) ->
+        let msg1 = msg0 <> " " <> showL opts n <> " " <> showL opts p
+            ret = splitAtNeg n p
+       in mkNode opts (PresentT ret) (show01' opts msg1 ret "n=" n <> showVerbose opts " | " p) [hh pp, hh qq]
+
+splitAtNeg :: Int -> [a] -> ([a], [a])
+splitAtNeg n as = splitAt (if n<0 then length as + n else n) as
+
+
+data Take n p
+type TakeT n p = Fst (SplitAt n p)
+
+instance P (TakeT n p) x => P (Take n p) x where
+  type PP (Take n p) x = PP (TakeT n p) x
+  eval _ = eval (Proxy @(TakeT n p))
+
+data Drop n p
+type DropT n p = Snd (SplitAt n p)
+
+instance P (DropT n p) x => P (Drop n p) x where
+  type PP (Drop n p) x = PP (DropT n p) x
+  eval _ = eval (Proxy @(DropT n p))
+
+-- | splits a list pointed to by \'p\' into lists of size \'n\'
+--
+-- >>> pz @(ChunksOf 2 Id) "abcdef"
+-- PresentT ["ab","cd","ef"]
+--
+-- >>> pz @(ChunksOf 2 Id) "abcdefg"
+-- PresentT ["ab","cd","ef","g"]
+--
+-- >>> pz @(ChunksOf 2 Id) ""
+-- PresentT []
+--
+-- >>> pz @(ChunksOf 2 Id) "a"
+-- PresentT ["a"]
+--
+data ChunksOf n p
+
+instance (PP p a ~ [b]
+        , P n a
+        , P p a
+        , Show b
+        , Integral (PP n a)
+        ) => P (ChunksOf n p) a where
+  type PP (ChunksOf n p) a = [PP p a]
+  eval _ opts a = do
+    let msg0 = "ChunksOf"
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (fromIntegral -> n,p,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+            msg1 = msg0 <> " " <> showL opts n <> " " <> showL opts p
+        in if n <= 0 then mkNode opts (FailT (msg0 <> " n<1")) "" hhs
+           else let ret = unfoldr (\s -> if null s then Nothing else Just $ splitAt n s) p
+                in mkNode opts (PresentT ret) (show01' opts msg1 ret "n=" n <> showVerbose opts " | " p) hhs
+
+-- empty lists at the type level wont work here
+
+data KeepImpl (keep :: Bool) p q
+
+instance (GetBool keep
+        , Eq a
+        , Show a
+        , P p x
+        , P q x
+        , PP p x ~ PP q x
+        , PP q x ~ [a]
+        ) => P (KeepImpl keep p q) x where
+  type PP (KeepImpl keep p q) x = PP q x
+  eval _ opts x = do
+    let msg0 = if keep then "Keep" else "Remove"
+        keep = getBool @keep
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let ret = filter (bool not id keep . (`elem` p)) q
+        in mkNode opts (PresentT ret) (show01' opts msg0 ret "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | filters a list \'q\' keeping those elements in \'p\'
+--
+-- >>> pz @(Keep '[5] '[1,5,5,2,5,2]) ()
+-- PresentT [5,5,5]
+--
+-- >>> pz @(Keep '[0,1,1,5] '[1,5,5,2,5,2]) ()
+-- PresentT [1,5,5,5]
+--
+data Keep p q
+type KeepT p q = KeepImpl 'True p q
+
+instance P (KeepT p q) x => P (Keep p q) x where
+  type PP (Keep p q) x = PP (KeepT p q) x
+  eval _ = eval (Proxy @(KeepT p q))
+
+-- | filters a list \'q\' removing those elements in \'p\'
+--
+-- >>> pz @(Remove '[5] '[1,5,5,2,5,2]) ()
+-- PresentT [1,2,2]
+--
+-- >>> pz @(Remove '[0,1,1,5] '[1,5,5,2,5,2]) ()
+-- PresentT [2,2]
+--
+-- >>> pz @(Remove '[99] '[1,5,5,2,5,2]) ()
+-- PresentT [1,5,5,2,5,2]
+--
+-- >>> pz @(Remove '[99,91] '[1,5,5,2,5,2]) ()
+-- PresentT [1,5,5,2,5,2]
+--
+-- >>> pz @(Remove Id '[1,5,5,2,5,2]) []
+-- PresentT [1,5,5,2,5,2]
+--
+-- >>> pz @(Remove '[] '[1,5,5,2,5,2]) 44 -- works if you make this a number!
+-- PresentT [1,5,5,2,5,2]
+--
+data Remove p q
+type RemoveT p q = KeepImpl 'False p q
+
+instance P (RemoveT p q) x => P (Remove p q) x where
+  type PP (Remove p q) x = PP (RemoveT p q) x
+  eval _ = eval (Proxy @(RemoveT p q))
+
+-- | takes the head of a list-like container: similar to 'head'
+--
+-- >>> pz @(Head Id) "abcd"
+-- PresentT 'a'
+--
+-- >>> pz @(Head Id) []
+-- FailT "Head(empty)"
+--
+-- >>> pl @(Head Id) ([] :: [Int])
+-- Error Head(empty)
+-- FailT "Head(empty)"
+--
+-- >>> pl @(Head Id) ([] :: [Double])
+-- Error Head(empty)
+-- FailT "Head(empty)"
+--
+-- >>> pl @(Head (Fst Id) >> Le 6) ([]::[Int], True)
+-- Error Head(empty) ((>>) lhs failed)
+-- FailT "Head(empty)"
+--
+-- >>> pl @(Head Id) [1,2,3]
+-- Present 1 (Head 1 | [1,2,3])
+-- PresentT 1
+--
+
+data Head p
+
+instance (Show (ConsT s)
+        , Show s
+        , Cons s s (ConsT s) (ConsT s)
+        , PP p x ~ s
+        , P p x
+        ) => P (Head p) x where
+  type PP (Head p) x = ConsT (PP p x)
+  eval _ opts x = do
+    let msg0 = "Head"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p ^? _Cons of
+          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
+          Just (a,_) -> mkNode opts (PresentT a) (show01 opts msg0 a p) [hh pp]
+
+-- | takes the tail of a list-like container: similar to 'tail'
+--
+-- >>> pz @(Tail Id) "abcd"
+-- PresentT "bcd"
+--
+-- >>> pl @(Tail Id) [1..5]
+-- Present [2,3,4,5] (Tail [2,3,4,5] | [1,2,3,4,5])
+-- PresentT [2,3,4,5]
+--
+-- >>> pl @(Tail Id) ([] :: [()])
+-- Error Tail(empty)
+-- FailT "Tail(empty)"
+--
+
+data Tail p
+
+instance (Show s
+        , Cons s s (ConsT s) (ConsT s)
+        , PP p x ~ s
+        , P p x
+        ) => P (Tail p) x where
+  type PP (Tail p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Tail"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p ^? _Cons of
+          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
+          Just (_,as) -> mkNode opts (PresentT as) (show01 opts msg0 as p) [hh pp]
+
+
+-- | takes the last of a list-like container: similar to 'last'
+--
+-- >>> pz @(Last Id) "abcd"
+-- PresentT 'd'
+--
+-- >>> pz @(Last Id) []
+-- FailT "Last(empty)"
+--
+-- >>> pl @(Last Id) [1,2,3]
+-- Present 3 (Last 3 | [1,2,3])
+-- PresentT 3
+--
+
+data Last p
+
+instance (Show (ConsT s)
+        , Show s
+        , Snoc s s (ConsT s) (ConsT s)
+        , PP p x ~ s
+        , P p x
+        ) => P (Last p) x where
+  type PP (Last p) x = ConsT (PP p x)
+  eval _ opts x = do
+    let msg0 = "Last"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p ^? _Snoc of
+          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
+          Just (_,a) -> mkNode opts (PresentT a) (show01 opts msg0 a p) [hh pp]
+
+-- | takes the init of a list-like container: similar to 'init'
+--
+-- >>> pz @(Init Id) "abcd"
+-- PresentT "abc"
+--
+-- >>> pz @(Init Id) (T.pack "abcd")
+-- PresentT "abc"
+--
+-- >>> pz @(Init Id) []
+-- FailT "Init(empty)"
+--
+-- >>> pl @(Init Id) [1..5]
+-- Present [1,2,3,4] (Init [1,2,3,4] | [1,2,3,4,5])
+-- PresentT [1,2,3,4]
+--
+-- >>> pl @(Init Id) ([] :: [()])
+-- Error Init(empty)
+-- FailT "Init(empty)"
+--
+data Init p
+
+instance (Show s
+        , Snoc s s (ConsT s) (ConsT s)
+        , PP p x ~ s
+        , P p x
+        ) => P (Init p) x where
+  type PP (Init p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Init"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        case p ^? _Snoc of
+          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
+          Just (as,_) -> mkNode opts (PresentT as) (show01 opts msg0 as p) [hh pp]
+
+
+-- | 'unzip' equivalent
+--
+-- >>> pz @Unzip (zip [1..5] "abcd")
+-- PresentT ([1,2,3,4],"abcd")
+--
+data Unzip
+type UnzipT = '(Map (Fst Id) Id, Map (Snd Id) Id)
+
+instance P UnzipT x => P Unzip x where
+  type PP Unzip x = PP UnzipT x
+  eval _ = eval (Proxy @UnzipT)
+
+
+-- | 'unzip3' equivalent
+--
+-- >>> pz @Unzip3 (zip3 [1..5] "abcd" (cycle [True,False]))
+-- PresentT ([1,2,3,4],"abcd",[True,False,True,False])
+--
+data Unzip3
+type Unzip3T = '(Map (Fst Id) Id, Map (Snd Id) Id, Map (Thd Id) Id)
+
+instance P Unzip3T x => P Unzip3 x where
+  type PP Unzip3 x = PP Unzip3T x
+  eval _ = eval (Proxy @Unzip3T)
+
+-- | sort a list
+--
+-- >>> pz @(SortOn (Fst Id) Id) [(10,"abc"), (3,"def"), (4,"gg"), (10,"xyz"), (1,"z")]
+-- PresentT [(1,"z"),(3,"def"),(4,"gg"),(10,"abc"),(10,"xyz")]
+--
+-- >>> pz @(SortBy (OrdP (Snd Id) (Fst Id)) Id) [(10,"ab"),(4,"x"),(20,"bbb")]
+-- PresentT [(20,"bbb"),(10,"ab"),(4,"x")]
+--
+-- >>> pz @(SortBy 'LT Id) [1,5,2,4,7,0]
+-- PresentT [1,5,2,4,7,0]
+--
+-- >>> pz @(SortBy 'GT Id) [1,5,2,4,7,0]
+-- PresentT [0,7,4,2,5,1]
+--
+-- >>> pz @(SortBy ((Fst (Fst Id) ==! Fst (Snd Id)) <> (Snd (Fst Id) ==! Snd (Snd Id))) Id) [(10,"ab"),(4,"x"),(20,"bbb"),(4,"a"),(4,"y")]
+-- PresentT [(4,"a"),(4,"x"),(4,"y"),(10,"ab"),(20,"bbb")]
+--
+-- >>> pz @(SortBy ((Fst (Fst Id) ==! Fst (Snd Id)) <> (Snd (Snd Id) ==! Snd (Fst Id))) Id) [(10,"ab"),(4,"x"),(20,"bbb"),(4,"a"),(4,"y")]
+-- PresentT [(4,"y"),(4,"x"),(4,"a"),(10,"ab"),(20,"bbb")]
+--
+-- >>> pl @(SortBy (Swap >> OrdA (Fst Id)) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
+-- Present [('z',1),('m',22),('a',10)] (SortBy [('z',1),('m',22),('a',10)])
+-- PresentT [('z',1),('m',22),('a',10)]
+--
+-- >>> pl @(SortBy (OrdA Reverse) Id) ["az","by","cx","aa"]
+-- Present ["aa","cx","by","az"] (SortBy ["aa","cx","by","az"])
+-- PresentT ["aa","cx","by","az"]
+--
+-- >>> pl @(SortBy (If (Fst Id==5 && Snd Id==3) (Failt _ (PrintT "pivot=%d value=%d" Id)) 'GT) (Snd Id)) ((), [5,7,3,1,6,2,1,3])
+-- Error pivot=5 value=3(2) (SortBy)
+-- FailT "pivot=5 value=3(2)"
+--
+-- >>> pl @(SortBy (If (Fst Id==50 && Snd Id==3) (Failt _ (PrintT "pivot=%d value=%d" Id)) (OrdA Id)) (Snd Id)) ((), [5,7,3,1,6,2,1,3])
+-- Present [1,1,2,3,3,5,6,7] (SortBy [1,1,2,3,3,5,6,7])
+-- PresentT [1,1,2,3,3,5,6,7]
+--
+data SortBy p q
+
+type SortByHelperT p = Partition (p == 'GT) Id
+
+instance (P p (a,a)
+        , P q x
+        , Show a
+        , PP q x ~ [a]
+        , PP p (a,a) ~ Ordering
+        ) => P (SortBy p q) x where
+  type PP (SortBy p q) x = PP q x
+  eval _ opts x = do
+    let msg0 = "SortBy"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts (msg0 <> " q failed") qq [] of
+      Left e -> pure e
+      Right as -> do
+        let ff :: MonadEval m => [a] -> m (TT [a])
+            ff = \case
+                [] -> pure $ mkNode opts (PresentT mempty) (msg0 <> " empty") [hh qq]
+                [w] -> pure $ mkNode opts (PresentT [w]) (msg0 <> " one element " <> showL opts w) [hh qq]
+                w:ys@(_:_) -> do
+                  pp <- evalHide @(SortByHelperT p) opts (map (w,) ys)
+                  case getValueLR opts msg0 pp [hh qq] of
+                    Left e -> pure e
+                    Right (ll', rr') -> do
+                      lhs <- ff (map snd ll')
+                      case getValueLR opts msg0 lhs [hh qq, hh pp] of
+                        Left _ -> pure lhs -- dont rewrap
+                        Right ll -> do
+                          rhs <- ff (map snd rr')
+                          case getValueLR opts msg0 rhs [hh qq, hh pp, hh lhs] of
+                            Left _ -> pure rhs
+                            Right rr ->
+                              pure $  mkNode opts (PresentT (ll ++ w : rr))
+                                     (msg0 <> " lhs=" <> showL opts ll <> " pivot " <> show w <> " rhs=" <> showL opts rr)
+                                     (hh pp : [hh lhs | length ll > 1] ++ [hh rhs | length rr > 1])
+        ret <- ff as
+        pure $ case getValueLR opts msg0 ret [hh qq] of
+          Left _e -> ret -- dont rewrap else will double up messages: already handled
+          Right xs -> mkNode opts (_tBool ret) (msg0 <> " " <> showL opts xs) [hh qq, hh ret]
+
+-- | similar to 'sortOn'
+--
+-- >>> pl @(SortOn Id Id) [10,4,2,12,14]
+-- Present [2,4,10,12,14] (SortBy [2,4,10,12,14])
+-- PresentT [2,4,10,12,14]
+--
+-- >>> pl @(SortOn (Negate Id) Id) [10,4,2,12,14]
+-- Present [14,12,10,4,2] (SortBy [14,12,10,4,2])
+-- PresentT [14,12,10,4,2]
+--
+-- >>> pl @(SortOn (Fst Id) Id) (zip "cabdaz" [10,4,2,12,14,1])
+-- Present [('a',4),('a',14),('b',2),('c',10),('d',12),('z',1)] (SortBy [('a',4),('a',14),('b',2),('c',10),('d',12),('z',1)])
+-- PresentT [('a',4),('a',14),('b',2),('c',10),('d',12),('z',1)]
+--
+-- >>> pl @(SortOn (FailS "asdf") Id) [10,4,2,12,14]
+-- Error asdf(4) (SortBy)
+-- FailT "asdf(4)"
+--
+-- >>> pl @(SortOn (Snd Id) (Snd Id)) ((),[('z',14),('a',10),('m',22),('a',1)])
+-- Present [('a',1),('a',10),('z',14),('m',22)] (SortBy [('a',1),('a',10),('z',14),('m',22)])
+-- PresentT [('a',1),('a',10),('z',14),('m',22)]
+--
+-- >>> pl @(SortOn (Fst Id) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
+-- Present [('a',10),('m',22),('z',1)] (SortBy [('a',10),('m',22),('z',1)])
+-- PresentT [('a',10),('m',22),('z',1)]
+--
+-- >>> pl @(SortOn (Fst Id) Id) [('z',1),('a',10),('m',22),('a',9),('m',10)]
+-- Present [('a',10),('a',9),('m',22),('m',10),('z',1)] (SortBy [('a',10),('a',9),('m',22),('m',10),('z',1)])
+-- PresentT [('a',10),('a',9),('m',22),('m',10),('z',1)]
+--
+-- >>> pl @(SortOn Id Id) [('z',1),('a',10),('m',22),('a',9),('m',10)]
+-- Present [('a',9),('a',10),('m',10),('m',22),('z',1)] (SortBy [('a',9),('a',10),('m',10),('m',22),('z',1)])
+-- PresentT [('a',9),('a',10),('m',10),('m',22),('z',1)]
+--
+data SortOn p q
+type SortOnT p q = SortBy (OrdA p) q
+
+instance P (SortOnT p q) x => P (SortOn p q) x where
+  type PP (SortOn p q) x = PP (SortOnT p q) x
+  eval _ = eval (Proxy @(SortOnT p q))
+
+-- | 'SortOn' but descending order
+--
+-- >>> pl @(SortOnDesc Id Id) [10,4,2,12,14]
+-- Present [14,12,10,4,2] (SortBy [14,12,10,4,2])
+-- PresentT [14,12,10,4,2]
+--
+-- >>> pl @(SortOnDesc (Fst Id) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
+-- Present [('z',1),('m',22),('a',10)] (SortBy [('z',1),('m',22),('a',10)])
+-- PresentT [('z',1),('m',22),('a',10)]
+--
+data SortOnDesc p q
+type SortOnDescT p q = SortBy (Swap >> OrdA p) q
+
+instance P (SortOnDescT p q) x => P (SortOnDesc p q) x where
+  type PP (SortOnDesc p q) x = PP (SortOnDescT p q) x
+  eval _ = eval (Proxy @(SortOnDescT p q))
+
+-- | similar to 'reverse'
+--
+-- >>> pz @Reverse [1,2,4]
+-- PresentT [4,2,1]
+--
+-- >>> pz @Reverse "AbcDeF"
+-- PresentT "FeDcbA"
+--
+data Reverse
+
+instance ( Show a
+         , as ~ [a]
+         ) => P Reverse as where
+  type PP Reverse as = as
+  eval _ opts as =
+    let msg0 = "Reverse"
+        d = reverse as
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d as) []
+
+-- | reverses using 'reversing'
+--
+-- >>> pz @ReverseL (T.pack "AbcDeF")
+-- PresentT "FeDcbA"
+--
+-- >>> pz @ReverseL ("AbcDeF" :: String)
+-- PresentT "FeDcbA"
+--
+-- >>> pl @ReverseL ("asfd" :: T.Text)
+-- Present "dfsa" (ReverseL "dfsa" | "asfd")
+-- PresentT "dfsa"
+--
+data ReverseL
+
+instance ( Show t
+         , Reversing t
+         ) => P ReverseL t where
+  type PP ReverseL t = t
+  eval _ opts as =
+    let msg0 = "ReverseL"
+        d = as ^. reversed
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d as) []
+
+-- | creates a singleton from a value
+--
+-- >>> pz @(Singleton (Char1 "aBc")) ()
+-- PresentT "a"
+--
+-- >>> pz @(Singleton Id) False
+-- PresentT [False]
+--
+-- >>> pz @(Singleton (Snd Id)) (False,"hello")
+-- PresentT ["hello"]
+--
+data Singleton p
+
+instance P p x => P (Singleton p) x where
+  type PP (Singleton p) x = [PP p x]
+  eval _ opts x = do
+    let msg0 = "Singleton"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p -> mkNode opts (PresentT [p]) msg0 [hh pp]
+
+data EmptyList' t
+
+instance P (EmptyList' t) x where
+  type PP (EmptyList' t) x = [PP t x]
+  eval _ opts _ =
+    pure $ mkNode opts (PresentT []) "EmptyList" []
+
+-- | creates an empty list for the given type
+--
+-- >>> pz @(Id :+ EmptyList _) 99
+-- PresentT [99]
+--
+data EmptyList (t :: Type)
+type EmptyListT (t :: Type) = EmptyList' (Hole t)
+
+instance P (EmptyList t) x where
+  type PP (EmptyList t) x = PP (EmptyListT t) x
+  eval _ = eval (Proxy @(EmptyListT t))
+
+
+-- | like 'zipWith'
+--
+-- >>> pz @(ZipWith Id (1...5) (Char1 "a" ... Char1 "e")) ()
+-- PresentT [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')]
+--
+-- >>> pz @(ZipWith (ShowP (Fst Id) <> ShowP (Snd Id)) (1...5) (Char1 "a" ... Char1 "e")) ()
+-- PresentT ["1'a'","2'b'","3'c'","4'd'","5'e'"]
+--
+-- >>> pz @(ZipWith (MkThese (Fst Id) (Snd Id)) (1...6) (Char1 "a" ... Char1 "f")) ()
+-- PresentT [These 1 'a',These 2 'b',These 3 'c',These 4 'd',These 5 'e',These 6 'f']
+--
+-- >>> pz @(ZipWith (MkThese (Fst Id) (Snd Id)) '[] (Char1 "a" ... Char1 "f")) ()
+-- FailT "ZipWith(0,6) length mismatch"
+--
+-- >>> pz @(ZipWith (MkThese (Fst Id) (Snd Id)) (1...3) (Char1 "a" ... Char1 "f")) ()
+-- FailT "ZipWith(3,6) length mismatch"
+--
+data ZipWith p q r
+
+instance (PP q a ~ [x]
+        , PP r a ~ [y]
+        , P q a
+        , P r a
+        , P p (x,y)
+        , Show x
+        , Show y
+        , Show (PP p (x,y))
+        ) => P (ZipWith p q r) a where
+  type PP (ZipWith p q r) a = [PP p (ExtractAFromList (PP q a), ExtractAFromList (PP r a))]
+  eval _ opts a = do
+    let msg0 = "ZipWith"
+    lr <- runPQ msg0 (Proxy @q) (Proxy @r) opts a []
+    case lr of
+      Left e -> pure e
+      Right (q,r,qq,rr) ->
+        let hhs = [hh qq, hh rr]
+        in case chkSize opts msg0 q hhs <* chkSize opts msg0 r hhs of
+          Left e -> pure e
+          Right () -> do
+            let lls = (length q, length r)
+            if uncurry (==) lls then do
+               ts <- zipWithM (\i (x,y) -> ((i, (x,y)),) <$> evalHide @p opts (x,y)) [0::Int ..] (zip q r)
+               pure $ case splitAndAlign opts msg0 ts of
+                 Left e -> e
+                 Right abcs ->
+                   let kvs = map (view _1 &&& ((:[]) . view (_2 . _2))) abcs
+                       itts = map (view _2 &&& view _3) abcs
+                       ret = map fst kvs
+                   in mkNode opts (PresentT ret) (show01' opts msg0 ret "s=" q ) (hh qq : map (hh . fixit) itts)
+
+             else do
+                   let msg1 = msg0 ++ show lls
+                   pure $ mkNode opts (FailT (msg1 <> " length mismatch")) (showVerbose opts "q=" q <> showVerbose opts " | r=" r) hhs
+
+-- | Zip two lists to their maximum length using optional padding
+--
+-- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abc", [1..5])
+-- PresentT [('a',1),('b',2),('c',3),('Z',4),('Z',5)]
+--
+-- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcdefg", [1..5])
+-- PresentT [('a',1),('b',2),('c',3),('d',4),('e',5),('f',99),('g',99)]
+--
+-- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcde", [1..5])
+-- PresentT [('a',1),('b',2),('c',3),('d',4),('e',5)]
+--
+-- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("", [1..5])
+-- PresentT [('Z',1),('Z',2),('Z',3),('Z',4),('Z',5)]
+--
+-- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcde", [])
+-- PresentT [('a',99),('b',99),('c',99),('d',99),('e',99)]
+--
+data ZipPad l r p q
+
+instance (PP l a ~ x
+        , PP r a ~ y
+        , P l a
+        , P r a
+        , PP p a ~ [x]
+        , PP q a ~ [y]
+        , P p a
+        , P q a
+        , Show x
+        , Show y
+        ) => P (ZipPad l r p q) a where
+  type PP (ZipPad l r p q) a = [(PP l a, PP r a)]
+  eval _ opts a = do
+    let msg0 = "ZipPad"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> pure e
+          Right () -> do
+            let lls = (length p,length q)
+            case uncurry compare lls of
+              LT -> do
+                ll <- eval (Proxy @l) opts a
+                pure $ case getValueLR opts (msg0 <> " l failed") ll hhs of
+                  Left e -> e
+                  Right l ->
+                    let d = zip (p ++ repeat l) q
+                    in mkNode opts (PresentT d) (show01' opts (msg0 <> " Left pad") d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh ll])
+              GT -> do
+                rr <- eval (Proxy @r) opts a
+                pure $ case getValueLR opts (msg0 <> " r failed") rr hhs of
+                  Left e -> e
+                  Right r ->
+                    let d =zip p (q ++ repeat r)
+                    in mkNode opts (PresentT d) (show01' opts (msg0 <> " Right pad") d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh rr])
+              EQ ->
+                let d = zip p q
+                in pure $ mkNode opts (PresentT d) (show01' opts (msg0 <> " No pad") d "p=" p <> showVerbose opts " | q=" q) hhs
+
+
+-- | zip two lists optionally padding the left hand side
+--
+-- >>> pl @(ZipL 99 '[1,2,3] "abc") ()
+-- Present [(1,'a'),(2,'b'),(3,'c')] (ZipL [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
+-- PresentT [(1,'a'),(2,'b'),(3,'c')]
+--
+-- >>> pl @(ZipL 99 '[1,2] "abc") ()
+-- Present [(1,'a'),(2,'b'),(99,'c')] (ZipL [(1,'a'),(2,'b'),(99,'c')] | p=[1,2] | q="abc")
+-- PresentT [(1,'a'),(2,'b'),(99,'c')]
+--
+-- >>> pl @(ZipL 99 '[1] "abc") ()
+-- Present [(1,'a'),(99,'b'),(99,'c')] (ZipL [(1,'a'),(99,'b'),(99,'c')] | p=[1] | q="abc")
+-- PresentT [(1,'a'),(99,'b'),(99,'c')]
+--
+-- >>> pl @(ZipL 99 '[1,2,3] "ab") ()
+-- Error ZipL(3,2) rhs would be truncated (p=[1,2,3] | q="ab")
+-- FailT "ZipL(3,2) rhs would be truncated"
+--
+-- >>> pl @(ZipL 99 Id "abcdefg") [1..4]
+-- Present [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(99,'e'),(99,'f'),(99,'g')] (ZipL [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(99,'e'),(99,'f'),(99,'g')] | p=[1,2,3,4] | q="abcdefg")
+-- PresentT [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(99,'e'),(99,'f'),(99,'g')]
+--
+-- >>> pl @(ZipL (99 % 4) '[1 % 1 , 2 % 1 , 3 % 1] Id) "abcde"
+-- Present [(1 % 1,'a'),(2 % 1,'b'),(3 % 1,'c'),(99 % 4,'d'),(99 % 4,'e')] (ZipL [(1 % 1,'a'),(2 % 1,'b'),(3 % 1,'c'),(99 % 4,'d'),(99 % 4,'e')] | p=[1 % 1,2 % 1,3 % 1] | q="abcde")
+-- PresentT [(1 % 1,'a'),(2 % 1,'b'),(3 % 1,'c'),(99 % 4,'d'),(99 % 4,'e')]
+--
+-- >>> pl @(ZipL "X" (EmptyT _ Id) Id) ("abcd" :: String)
+-- Present [("X",'a'),("X",'b'),("X",'c'),("X",'d')] (ZipL [("X",'a'),("X",'b'),("X",'c'),("X",'d')] | p=[] | q="abcd")
+-- PresentT [("X",'a'),("X",'b'),("X",'c'),("X",'d')]
+--
+
+data ZipL l p q
+instance (PP l a ~ x
+        , P l a
+        , PP p a ~ [x]
+        , PP q a ~ [y]
+        , P p a
+        , P q a
+        , Show x
+        , Show y
+        ) => P (ZipL l p q) a where
+  type PP (ZipL l p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
+  eval _ opts a = do
+    let msg0 = "ZipL"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> pure e
+          Right () -> do
+            let lls = (length p,length q)
+            case uncurry compare lls of
+              GT -> let msg1 = msg0 ++ show lls
+                    in pure $ mkNode opts (FailT (msg1 ++ " rhs would be truncated")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
+              _ -> do
+                     ll <- eval (Proxy @l) opts a
+                     pure $ case getValueLR opts (msg0 <> " l failed") ll hhs of
+                             Left e -> e
+                             Right l ->
+                               let d = zip (p ++ repeat l) q
+                               in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh ll])
+
+-- | zip two lists optionally padding the right hand side
+--
+-- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "abc") ()
+-- Present [(1,'a'),(2,'b'),(3,'c')] (ZipR [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
+-- PresentT [(1,'a'),(2,'b'),(3,'c')]
+--
+-- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "ab") ()
+-- Present [(1,'a'),(2,'b'),(3,'Z')] (ZipR [(1,'a'),(2,'b'),(3,'Z')] | p=[1,2,3] | q="ab")
+-- PresentT [(1,'a'),(2,'b'),(3,'Z')]
+--
+-- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "a") ()
+-- Present [(1,'a'),(2,'Z'),(3,'Z')] (ZipR [(1,'a'),(2,'Z'),(3,'Z')] | p=[1,2,3] | q="a")
+-- PresentT [(1,'a'),(2,'Z'),(3,'Z')]
+--
+-- >>> pl @(ZipR (Char1 "Z") '[1,2] "abc") ()
+-- Error ZipR(2,3) rhs would be truncated (p=[1,2] | q="abc")
+-- FailT "ZipR(2,3) rhs would be truncated"
+--
+-- >>> pl @(ZipR (Char1 "Y") (EmptyT _ Id) Id) "abcd"
+-- Error ZipR(0,4) rhs would be truncated (p=[] | q="abcd")
+-- FailT "ZipR(0,4) rhs would be truncated"
+--
+
+data ZipR r p q
+instance (PP r a ~ y
+        , P r a
+        , PP p a ~ [x]
+        , PP q a ~ [y]
+        , P p a
+        , P q a
+        , Show x
+        , Show y
+        ) => P (ZipR r p q) a where
+  type PP (ZipR r p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
+  eval _ opts a = do
+    let msg0 = "ZipR"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) -> do
+        let hhs = [hh pp, hh qq]
+        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> pure e
+          Right () -> do
+            let lls = (length p,length q)
+            case uncurry compare lls of
+              LT -> let msg1 = msg0 ++ show lls
+                    in pure $ mkNode opts (FailT (msg1 ++ " rhs would be truncated")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
+              _ -> do
+                     rr <- eval (Proxy @r) opts a
+                     pure $ case getValueLR opts (msg0 <> " l failed") rr hhs of
+                             Left e -> e
+                             Right r ->
+                               let d = zip p (q ++ repeat r)
+                               in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh rr])
+
+-- | zip two lists with the same length
+--
+-- >>> pl @(Zip '[1,2,3] "abc") ()
+-- Present [(1,'a'),(2,'b'),(3,'c')] (Zip [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
+-- PresentT [(1,'a'),(2,'b'),(3,'c')]
+--
+-- >>> pl @(Zip '[1,2,3] "ab") ()
+-- Error Zip(3,2) length mismatch (p=[1,2,3] | q="ab")
+-- FailT "Zip(3,2) length mismatch"
+--
+-- >>> pl @(Zip '[1,2] "abc") ()
+-- Error Zip(2,3) length mismatch (p=[1,2] | q="abc")
+-- FailT "Zip(2,3) length mismatch"
+--
+-- >>> pl @(Zip "abc" Id) [1..7]
+-- Error Zip(3,7) length mismatch (p="abc" | q=[1,2,3,4,5,6,7])
+-- FailT "Zip(3,7) length mismatch"
+--
+data Zip p q
+instance (PP p a ~ [x]
+        , PP q a ~ [y]
+        , P p a
+        , P q a
+        , Show x
+        , Show y
+        ) => P (Zip p q) a where
+  type PP (Zip p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
+  eval _ opts a = do
+    let msg0 = "Zip"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> e
+          Right () ->
+            let lls = (length p, length q)
+            in case uncurry compare lls of
+                 EQ -> let d = zip p q
+                       in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) hhs
+                 _ -> let msg1 = msg0 ++ show lls
+                      in mkNode opts (FailT (msg1 <> " length mismatch")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
+
+-- | similar to 'empty'
+--
+-- >>> pz @(EmptyT Maybe Id) ()
+-- PresentT Nothing
+--
+-- >>> pz @(EmptyT [] Id) ()
+-- PresentT []
+--
+-- >>> pz @(EmptyT [] (Char1 "x")) (13,True)
+-- PresentT ""
+--
+-- >>> pz @(EmptyT (Either String) (Fst Id)) (13,True)
+-- PresentT (Left "")
+--
+data EmptyT (t :: Type -> Type) p
+
+instance (P p x
+        , PP p x ~ a
+        , Show (t a)
+        , Show a
+        , Alternative t
+        ) => P (EmptyT t p) x where
+  type PP (EmptyT t p) x = t (PP p x)
+  eval _ opts x = do
+    let msg0 = "EmptyT"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = empty @t
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+
+-- | similar to 'sum'
+--
+-- >>> pz @Sum [10,4,5,12,3,4]
+-- PresentT 38
+--
+-- >>> pz @Sum []
+-- PresentT 0
+--
+data Sum
+
+instance ( Num a
+         , Show a
+         ) => P Sum [a] where
+  type PP Sum [a] = a
+  eval _ opts as =
+    let msg0 = "Sum"
+        v = sum as
+    in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
+
+-- | similar to 'product'
+--
+-- >>> pz @Product [10,4,5,12,3,4]
+-- PresentT 28800
+--
+-- >>> pz @Product []
+-- PresentT 1
+--
+data Product
+
+instance ( Num a
+         , Show a
+         ) => P Product [a] where
+  type PP Product [a] = a
+  eval _ opts as =
+    let msg0 = "Product"
+        v = product as
+    in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
+
+-- | similar to 'minimum'
+--
+-- >>> pz @Min [10,4,5,12,3,4]
+-- PresentT 3
+--
+-- >>> pz @Min []
+-- FailT "empty list"
+--
+data Min
+
+instance ( Ord a
+         , Show a
+         ) => P Min [a] where
+  type PP Min [a] = a
+  eval _ opts as' = do
+    let msg0 = "Min"
+    pure $ case as' of
+     [] -> mkNode opts (FailT "empty list") msg0 []
+     as@(_:_) ->
+       let v = minimum as
+       in mkNode opts (PresentT v) (show01 opts msg0 v as) []
+
+-- | similar to 'maximum'
+--
+-- >>> pz @Max [10,4,5,12,3,4]
+-- PresentT 12
+--
+-- >>> pz @Max []
+-- FailT "empty list"
+--
+
+data Max
+
+instance ( Ord a
+         , Show a
+         ) => P Max [a] where
+  type PP Max [a] = a
+  eval _ opts as' = do
+    let msg0 = "Max"
+    pure $ case as' of
+      [] -> mkNode opts (FailT "empty list") msg0 []
+      as@(_:_) ->
+        let v = maximum as
+        in mkNode opts (PresentT v) (show01 opts msg0 v as) []
+
+ src/Predicate/Data/Maybe.hs view
@@ -0,0 +1,487 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted 'Maybe' functions
+-}
+module Predicate.Data.Maybe (
+
+ -- ** boolean predicates
+    IsNothing
+  , IsJust
+
+ -- ** constructors
+  , MkNothing
+  , MkNothing'
+  , MkJust
+
+ -- ** get rid of Maybe
+  , Just'
+  , JustDef
+  , JustFail
+  , MapMaybe
+  , CatMaybes
+  , MaybeIn
+  , MaybeBool
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Foldable (ConcatMap)
+import Predicate.Data.Monoid (MEmptyP)
+import Data.Proxy
+import Data.Kind (Type)
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Map.Strict as M
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+
+-- | similar to 'Data.Maybe.fromJust'
+--
+-- >>> pz @(Just' >> Succ Id) (Just 20)
+-- PresentT 21
+--
+-- >>> pz @(Just' >> Succ Id) Nothing
+-- FailT "Just' found Nothing"
+--
+data Just'
+instance (Show a
+        ) => P Just' (Maybe a) where
+  type PP Just' (Maybe a) = a
+  eval _ opts lr =
+    let msg0 = "Just'"
+    in pure $ case lr of
+         Nothing -> mkNode opts (FailT (msg0 <> " found Nothing")) "" []
+         Just a -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | constructs a Nothing for a given type
+data MkNothing' t -- works always! MaybeBool is a good alternative and then dont need the extra 't'
+
+-- for this to be useful has to have 't' else we end up with tons of problems
+instance P (MkNothing' t) a where
+  type PP (MkNothing' t) a = Maybe (PP t a)
+  eval _ opts _ =
+    let msg0 = "MkNothing"
+    in pure $ mkNode opts (PresentT Nothing) msg0 []
+
+-- | constructs a Nothing for a given type
+data MkNothing (t :: Type)
+type MkNothingT (t :: Type) = MkNothing' (Hole t)
+
+instance P (MkNothing t) x where
+  type PP (MkNothing t) x = PP (MkNothingT t) x
+  eval _ = eval (Proxy @(MkNothingT t))
+
+-- | 'GHC.Maybe.Just' constructor
+--
+-- >>> pz @(MkJust Id) 44
+-- PresentT (Just 44)
+--
+data MkJust p
+instance ( PP p x ~ a
+         , P p x
+         , Show a
+         ) => P (MkJust p) x where
+  type PP (MkJust p) x = Maybe (PP p x)
+  eval _ opts x = do
+    let msg0 = "MkJust"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = Just p
+        in mkNode opts (PresentT d) (msg0 <> " Just " <> showL opts p) [hh pp]
+
+-- | similar to 'Data.Maybe.maybe'
+--
+-- provides a Proxy to the result of \'q\' but does not provide the surrounding context
+--
+-- >>> pz @(MaybeIn "foundnothing" (ShowP (Pred Id))) (Just 20)
+-- PresentT "19"
+--
+-- >>> pz @(MaybeIn "found nothing" (ShowP (Pred Id))) Nothing
+-- PresentT "found nothing"
+--
+-- >>> pl @(MaybeIn 'True Id) (Nothing @Bool) -- need @() else breaks
+-- True (MaybeIn(Nothing) True | Proxy)
+-- TrueT
+--
+-- >>> pl @(MaybeIn (Failt _ "failed4") Id) (Just 10)
+-- Present 10 (MaybeIn(Just) 10 | 10)
+-- PresentT 10
+--
+-- >>> pl @(MaybeIn 'False Id) (Nothing @Bool) -- breaks otherwise
+-- False (MaybeIn(Nothing) False | Proxy)
+-- FalseT
+--
+-- >>> pl @(MaybeIn MEmptyP Id) (Just [1,2,3])
+-- Present [1,2,3] (MaybeIn(Just) [1,2,3] | [1,2,3])
+-- PresentT [1,2,3]
+--
+-- >>> pl @(MaybeIn MEmptyP Id) (Nothing @[Int])
+-- Present [] (MaybeIn(Nothing) [] | Proxy)
+-- PresentT []
+--
+-- >>> pl @(MaybeIn (Failp "err") (Succ Id)) (Just 116)
+-- Present 117 (MaybeIn(Just) 117 | 116)
+-- PresentT 117
+--
+-- >>> pl @(MaybeIn 99 (Succ Id)) (Nothing @Int)
+-- Present 99 (MaybeIn(Nothing) 99 | Proxy)
+-- PresentT 99
+--
+-- >>> pl @(MaybeIn (Failp "someval") (Succ Id)) (Nothing @())
+-- Error someval (MaybeIn(Nothing))
+-- FailT "someval"
+--
+-- >>> pl @(MaybeIn 'True 'False) (Nothing @())
+-- True (MaybeIn(Nothing) True | Proxy)
+-- TrueT
+--
+-- >>> pl @(MaybeIn 'True 'False) (Just "aa")
+-- False (MaybeIn(Just) False | "aa")
+-- FalseT
+--
+-- >>> pl @(MaybeIn MEmptyP (Fst Id ==! Snd Id)) (Just ('x','z'))
+-- Present LT (MaybeIn(Just) LT | ('x','z'))
+-- PresentT LT
+--
+-- >>> pl @(MaybeIn MEmptyP (Fst Id ==! Snd Id)) (Nothing @(Char,Char))
+-- Present EQ (MaybeIn(Nothing) EQ | Proxy)
+-- PresentT EQ
+--
+-- >>> pl @(MaybeIn (Failp "failed20") 'False) (Nothing @Int)
+-- Error failed20 (MaybeIn(Nothing))
+-- FailT "failed20"
+--
+-- >>> pl @(MaybeIn ('False >> FailS "failed21") 'False) (Nothing @Double)
+-- Error failed21 (MaybeIn(Nothing))
+-- FailT "failed21"
+--
+-- >>> pl @(MaybeIn (Failp "err") Id) (Nothing @Int)
+-- Error err (MaybeIn(Nothing))
+-- FailT "err"
+--
+-- >>> pl @(MaybeIn (Failp "err") Id) (Nothing @())
+-- Error err (MaybeIn(Nothing))
+-- FailT "err"
+--
+-- >>> pl @(MaybeIn MEmptyP Id) (Just (M.fromList [(1,'a')]))
+-- Present fromList [(1,'a')] (MaybeIn(Just) fromList [(1,'a')] | fromList [(1,'a')])
+-- PresentT (fromList [(1,'a')])
+--
+-- >>> pl @(MaybeIn MEmptyP Id) (Nothing @(M.Map () ()))
+-- Present fromList [] (MaybeIn(Nothing) fromList [] | Proxy)
+-- PresentT (fromList [])
+--
+-- >>> pl @(MaybeIn MEmptyP (Ones Id)) (Just @String "abc")
+-- Present ["a","b","c"] (MaybeIn(Just) ["a","b","c"] | "abc")
+-- PresentT ["a","b","c"]
+--
+-- >>> pl @(MaybeIn 99 Id) (Just 12)
+-- Present 12 (MaybeIn(Just) 12 | 12)
+-- PresentT 12
+--
+-- >>> pl @(MaybeIn 99 Id) Nothing
+-- Present 99 (MaybeIn(Nothing) 99 | Proxy)
+-- PresentT 99
+--
+-- >>> pl @(MaybeIn (99 -% 1) Id) Nothing
+-- Present (-99) % 1 (MaybeIn(Nothing) (-99) % 1 | Proxy)
+-- PresentT ((-99) % 1)
+--
+-- >>> pl @(MaybeIn 123 Id) (Nothing @Int)
+-- Present 123 (MaybeIn(Nothing) 123 | Proxy)
+-- PresentT 123
+--
+-- >>> pl @(MaybeIn 123 Id) (Just 9)
+-- Present 9 (MaybeIn(Just) 9 | 9)
+-- PresentT 9
+--
+-- >>> pl @(Uncons >> MaybeIn '(1,MEmptyT _) Id) []
+-- Present (1,[]) ((>>) (1,[]) | {MaybeIn(Nothing) (1,[]) | Proxy})
+-- PresentT (1,[])
+--
+-- >>> pl @(MaybeIn MEmptyP (Ones (ShowP Id))) (Just 123)
+-- Present ["1","2","3"] (MaybeIn(Just) ["1","2","3"] | 123)
+-- PresentT ["1","2","3"]
+--
+-- >>> pl @(MaybeIn MEmptyP (Ones (ShowP Id))) (Nothing @String)
+-- Present [] (MaybeIn(Nothing) [] | Proxy)
+-- PresentT []
+--
+-- >>> pl @(MaybeIn MEmptyP (Ones Id)) (Just @String "ab")
+-- Present ["a","b"] (MaybeIn(Just) ["a","b"] | "ab")
+-- PresentT ["a","b"]
+--
+-- >>> pl @(MaybeIn MEmptyP (Ones Id)) (Nothing @String)
+-- Present [] (MaybeIn(Nothing) [] | Proxy)
+-- PresentT []
+--
+data MaybeIn p q
+
+-- tricky: the nothing case is the proxy of PP q a: ie proxy of the final result
+instance (P q a
+        , Show a
+        , Show (PP q a)
+        , PP p (Proxy (PP q a)) ~ PP q a
+        , P p (Proxy (PP q a))
+        ) => P (MaybeIn p q) (Maybe a) where
+  type PP (MaybeIn p q) (Maybe a) = PP q a
+  eval _ opts ma = do
+    let msg0 = "MaybeIn"
+    case ma of
+      Nothing -> do
+        let msg1 = msg0 <> "(Nothing)"
+        pp <- eval (Proxy @p) opts (Proxy @(PP q a))
+        pure $ case getValueLR opts msg1 pp [] of
+          Left e -> e
+          Right b -> mkNode opts (_tBool pp) (msg1 <> " " <> showL opts b <> " | Proxy") [hh pp]
+      Just a -> do
+        let msg1 = msg0 <> "(Just)"
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg1 qq [] of
+          Left e -> e
+          Right b -> mkNode opts (_tBool qq) (show01 opts msg1 b a) [hh qq]
+
+-- | similar to 'Data.Maybe.isJust'
+--
+-- >>> pz @(IsJust Id) Nothing
+-- FalseT
+--
+-- >>> pz @(IsJust Id) (Just 'a')
+-- TrueT
+--
+data IsJust p
+
+instance ( P p x
+         , PP p x ~ Maybe a
+         ) => P (IsJust p) x where
+  type PP (IsJust p) x = Bool
+  eval _ opts x = do
+    let msg0 = "IsJust"
+    pp <- eval (Proxy @p) opts x
+    let hhs = [hh pp]
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right (Just _) -> mkNodeB opts True msg0 hhs
+      Right Nothing -> mkNodeB opts False msg0 hhs
+
+-- | similar to 'Data.Maybe.isNothing'
+--
+-- >>> pz @(IsNothing Id) (Just 123)
+-- FalseT
+--
+-- >>> pz @(IsNothing Id) Nothing
+-- TrueT
+--
+-- >>> pl @(Not (IsNothing Id) &&& ('Just Id >> Id + 12)) (Just 1)
+-- Present (True,13) (W '(True,13))
+-- PresentT (True,13)
+--
+-- >>> pl @(Not (IsNothing Id) &&& ('Just Id >> Id + 12)) Nothing
+-- Error 'Just(empty) (W '(,))
+-- FailT "'Just(empty)"
+--
+data IsNothing p
+
+instance ( P p x
+         , PP p x ~ Maybe a
+         ) => P (IsNothing p) x where
+  type PP (IsNothing p) x = Bool
+  eval _ opts x = do
+    let msg0 = "IsNothing"
+    pp <- eval (Proxy @p) opts x
+    let hhs = [hh pp]
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right (Just _) -> mkNodeB opts False msg0 hhs
+      Right Nothing -> mkNodeB opts True msg0 hhs
+
+-- | like 'Data.Maybe.mapMaybe'
+--
+-- >>> pl @(MapMaybe (MaybeBool (Le 3) Id) Id) [1..5]
+-- Present [1,2,3] (Concat [1,2,3] | [[1],[2],[3],[],[]])
+-- PresentT [1,2,3]
+--
+-- >>> pl @(MapMaybe (MaybeBool (Gt 3) Id) Id) [1..5]
+-- Present [4,5] (Concat [4,5] | [[],[],[],[4],[5]])
+-- PresentT [4,5]
+--
+data MapMaybe p q
+type MapMaybeT p q = ConcatMap (p >> MaybeIn MEmptyP '[Id]) q
+
+instance P (MapMaybeT p q) x => P (MapMaybe p q) x where
+  type PP (MapMaybe p q) x = PP (MapMaybeT p q) x
+  eval _ = eval (Proxy @(MapMaybeT p q))
+
+-- | similar to 'Data.Maybe.catMaybes'
+--
+-- >>> pl @(CatMaybes Id) [Just 'a',Nothing,Just 'c',Just 'd',Nothing]
+-- Present "acd" (Concat "acd" | ["a","","c","d",""])
+-- PresentT "acd"
+--
+data CatMaybes q
+type CatMaybesT q = MapMaybe Id q
+
+instance P (CatMaybesT q) x => P (CatMaybes q) x where
+  type PP (CatMaybes q) x = PP (CatMaybesT q) x
+  eval _ = eval (Proxy @(CatMaybesT q))
+
+-- | Convenient method to convert a value \'p\' to a 'Maybe' based on a predicate \'b\'
+-- if \'b\' then Just \'p\' else Nothing
+--
+-- >>> pz @(MaybeBool (Id > 4) Id) 24
+-- PresentT (Just 24)
+--
+-- >>> pz @(MaybeBool (Id > 4) Id) (-5)
+-- PresentT Nothing
+--
+data MaybeBool b p
+
+instance (Show (PP p a)
+        , P b a
+        , P p a
+        , PP b a ~ Bool
+        ) => P (MaybeBool b p) a where
+  type PP (MaybeBool b p) a = Maybe (PP p a)
+  eval _ opts z = do
+    let msg0 = "MaybeBool"
+    bb <- evalBool (Proxy @b) opts z
+    case getValueLR opts (msg0 <> " b failed") bb [] of
+      Left e -> pure e
+      Right True -> do
+        pp <- eval (Proxy @p) opts z
+        pure $ case getValueLR opts (msg0 <> " p failed") pp [hh bb] of
+          Left e -> e
+          Right p -> mkNode opts (PresentT (Just p)) (msg0 <> "(False) Just " <> showL opts p) [hh bb, hh pp]
+      Right False -> pure $ mkNode opts (PresentT Nothing) (msg0 <> "(True)") [hh bb]
+
+-- | extract the value from a 'Maybe' otherwise use the default value: similar to 'Data.Maybe.fromMaybe'
+--
+-- >>> pz @(JustDef (1 % 4) Id) (Just 20.4)
+-- PresentT (102 % 5)
+--
+-- >>> pz @(JustDef (1 % 4) Id) Nothing
+-- PresentT (1 % 4)
+--
+-- >>> pz @(JustDef (MEmptyT _) Id) (Just "xy")
+-- PresentT "xy"
+--
+-- >>> pz @(JustDef (MEmptyT _) Id) Nothing
+-- PresentT ()
+--
+-- >>> pz @(JustDef (MEmptyT (SG.Sum _)) Id) Nothing
+-- PresentT (Sum {getSum = 0})
+--
+-- >>> pl @(JustDef 0 Id) (Just 123)
+-- Present 123 (JustDef Just)
+-- PresentT 123
+--
+-- >>> pl @(JustDef 0 Id) Nothing
+-- Present 0 (JustDef Nothing)
+-- PresentT 0
+--
+-- >>> pl @(JustDef 99 Id) (Just 12)
+-- Present 12 (JustDef Just)
+-- PresentT 12
+--
+-- >>> pl @(JustDef 99 Id) Nothing
+-- Present 99 (JustDef Nothing)
+-- PresentT 99
+--
+-- >>> pl @(JustDef (99 -% 1) Id) Nothing
+-- Present (-99) % 1 (JustDef Nothing)
+-- PresentT ((-99) % 1)
+--
+-- >>> pl @(JustDef (MEmptyT _) Id) (Just (SG.Sum 123))
+-- Present Sum {getSum = 123} (JustDef Just)
+-- PresentT (Sum {getSum = 123})
+--
+-- >>> pl @(JustDef (MEmptyT _) Id) (Nothing @(SG.Sum _))
+-- Present Sum {getSum = 0} (JustDef Nothing)
+-- PresentT (Sum {getSum = 0})
+--
+data JustDef p q
+
+instance ( PP p x ~ a
+         , PP q x ~ Maybe a
+         , P p x
+         , P q x)
+    => P (JustDef p q) x where
+  type PP (JustDef p q) x = MaybeT (PP q x)
+  eval _ opts x = do
+    let msg0 = "JustDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Just b -> pure $ mkNode opts (PresentT b) (msg0 <> " Just") [hh qq]
+          Nothing -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right b -> mkNode opts (PresentT b) (msg0 <> " Nothing") [hh qq, hh pp]
+
+
+-- | extract the value from a 'Maybe' or fail with the given message
+--
+-- >>> pz @(JustFail "nope" Id) (Just 99)
+-- PresentT 99
+--
+-- >>> pz @(JustFail "nope" Id) Nothing
+-- FailT "nope"
+--
+-- >>> pz @(JustFail (PrintF "oops=%d" (Snd Id)) (Fst Id)) (Nothing, 123)
+-- FailT "oops=123"
+--
+-- >>> pz @(JustFail (PrintF "oops=%d" (Snd Id)) (Fst Id)) (Just 'x', 123)
+-- PresentT 'x'
+--
+data JustFail p q
+
+instance ( PP p x ~ String
+         , PP q x ~ Maybe a
+         , P p x
+         , P q x)
+    => P (JustFail p q) x where
+  type PP (JustFail p q) x = MaybeT (PP q x)
+  eval _ opts x = do
+    let msg0 = "JustFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          Just b -> pure $ mkNode opts (PresentT b) (msg0 <> " Just") [hh qq]
+          Nothing -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " Nothing") [hh qq, hh pp]
+ src/Predicate/Data/Monoid.hs view
@@ -0,0 +1,314 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+          promoted 'Semigroup' and 'Monoid' functions
+-}
+module Predicate.Data.Monoid (
+
+  -- ** semigroup / monoid expressions
+    type (<>)
+  , MConcat
+  , SConcat
+  , STimes
+  , SapA
+  , SapA'
+  , MEmptyT
+  , MEmptyT'
+  , MEmptyP
+  , MEmpty2
+  , MEmpty2'
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Data.Proxy
+import Data.Kind (Type)
+import qualified Data.Semigroup as SG
+import Data.List.NonEmpty (NonEmpty(..))
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.Functor.Identity
+
+-- | similar to 'SG.<>'
+--
+-- >>> pz @(Fst Id <> Snd Id) ("abc","def")
+-- PresentT "abcdef"
+--
+-- >>> pz @("abcd" <> "ef" <> Id) "ghi"
+-- PresentT "abcdefghi"
+--
+-- >>> pz @("abcd" <> "ef" <> Id) "ghi"
+-- PresentT "abcdefghi"
+--
+-- >>> pz @(Wrap (SG.Sum _) Id <> FromInteger _ 10) 13
+-- PresentT (Sum {getSum = 23})
+--
+-- >>> pz @(Wrap (SG.Product _) Id <> FromInteger _ 10) 13
+-- PresentT (Product {getProduct = 130})
+--
+-- >>> pz @('(FromInteger _ 10,"def") <> Id) (SG.Sum 12, "_XYZ")
+-- PresentT (Sum {getSum = 22},"def_XYZ")
+--
+-- >>> pz @(SapA' (SG.Max _)) (10,12)
+-- PresentT (Max {getMax = 12})
+--
+-- >>> pz @(SapA' (SG.Sum _)) (10,12)
+-- PresentT (Sum {getSum = 22})
+--
+-- >>> pl @((Id <> Id) >> Unwrap Id) (SG.Sum 12)
+-- Present 24 ((>>) 24 | {getSum = 24})
+-- PresentT 24
+--
+data p <> q
+infixr 6 <>
+
+instance (Semigroup (PP p x)
+        , PP p x ~ PP q x
+        , P p x
+        , Show (PP q x)
+        ,P q x
+        ) => P (p <> q) x where
+  type PP (p <> q) x = PP p x
+  eval _ opts x = do
+    let msg0 = "<>"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = p <> q
+        in mkNode opts (PresentT d) (showL opts p <> " <> " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
+
+-- | semigroup append both sides of a tuple (ie uncurry (<>)) using 'Wrap'
+--
+-- >>> pl @(SapA' (SG.Sum _) >> Unwrap Id) (4,5)
+-- Present 9 ((>>) 9 | {getSum = 9})
+-- PresentT 9
+--
+data SapA' (t :: Type)
+type SapAT' (t :: Type) = Wrap t (Fst Id) <> Wrap t (Snd Id)
+
+instance P (SapAT' t) x => P (SapA' t) x where
+  type PP (SapA' t) x = PP (SapAT' t) x
+  eval _ = eval (Proxy @(SapAT' t))
+
+-- | semigroup append both sides of a tuple (ie uncurry (<>))
+--
+-- >>> pz @(Snd Id >> SapA) (4,("abc","def"))
+-- PresentT "abcdef"
+--
+data SapA
+type SapAT = Fst Id <> Snd Id
+
+instance P SapAT x => P SapA x where
+  type PP SapA x = PP SapAT x
+  eval _ = eval (Proxy @SapAT)
+
+-- | similar to 'mconcat'
+--
+-- >>> pz @(MConcat Id) [SG.Sum 44, SG.Sum 12, SG.Sum 3]
+-- PresentT (Sum {getSum = 59})
+--
+-- >>> pz @(Map '(Pure SG.Sum Id, Pure SG.Max Id) Id >> MConcat Id) [7 :: Int,6,1,3,5] -- monoid so need eg Int
+-- PresentT (Sum {getSum = 22},Max {getMax = 7})
+--
+data MConcat p
+
+instance (PP p x ~ [a]
+        , P p x
+        , Show a
+        , Monoid a
+        ) => P (MConcat p) x where
+  type PP (MConcat p) x = ExtractAFromList (PP p x)
+  eval _ opts x = do
+    let msg0 = "MConcat"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = mconcat p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+-- | similar to 'SG.sconcat'
+--
+-- >>> pz @(ToNEList >> SConcat Id) [SG.Sum 44, SG.Sum 12, SG.Sum 3]
+-- PresentT (Sum {getSum = 59})
+--
+-- >>> pz @(Map '(Pure SG.Sum Id, Pure SG.Max Id) Id >> ToNEList >> SConcat Id) [7,6,1,3,5]
+-- PresentT (Sum {getSum = 22},Max {getMax = 7})
+--
+data SConcat p
+
+instance (PP p x ~ NonEmpty a
+        , P p x
+        , Show a
+        , Semigroup a
+        ) => P (SConcat p) x where
+  type PP (SConcat p) x = ExtractAFromTA (PP p x)
+  eval _ opts x = do
+    let msg0 = "SConcat"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = SG.sconcat p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+-- | lift mempty over a Functor
+data MEmpty2' t
+
+instance (Show (f a)
+        , Show (f (PP t (f a)))
+        , Functor f
+        , Monoid (PP t (f a))
+        ) => P (MEmpty2' t) (f a) where
+  type PP (MEmpty2' t) (f a) = f (PP t (f a))
+  eval _ opts fa =
+    let msg0 = "MEmpty2"
+        b = mempty <$> fa
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b fa) []
+
+-- | lift mempty over a Functor
+--
+-- >>> pz @(MEmpty2 (SG.Product Int)) [Identity (-13), Identity 4, Identity 99]
+-- PresentT [Product {getProduct = 1},Product {getProduct = 1},Product {getProduct = 1}]
+--
+-- >>> pl @(MEmpty2 (SG.Sum _)) (Just ())
+-- Present Just (Sum {getSum = 0}) (MEmpty2 Just (Sum {getSum = 0}) | Just ())
+-- PresentT (Just (Sum {getSum = 0}))
+--
+data MEmpty2 (t :: Type)
+type MEmpty2T (t :: Type) = MEmpty2' (Hole t)
+
+instance P (MEmpty2T t) x => P (MEmpty2 t) x where
+  type PP (MEmpty2 t) x = PP (MEmpty2T t) x
+  eval _ = eval (Proxy @(MEmpty2T t))
+
+-- | similar to 'mempty'
+--
+-- >>> pl @(MEmptyT' Id) (Just (SG.Sum 12))
+-- Present Nothing (MEmptyT Nothing)
+-- PresentT Nothing
+--
+-- >>> pl @(MEmptyT (SG.Sum _) >> Unwrap Id >> Id + 4) ()
+-- Present 4 ((>>) 4 | {0 + 4 = 4})
+-- PresentT 4
+--
+
+-- no Monoid for Maybe a unless a is also a monoid but can use empty!
+data MEmptyT' t
+instance ( Show (PP t a)
+         , Monoid (PP t a)
+         ) => P (MEmptyT' t) a where
+  type PP (MEmptyT' t) a = PP t a
+  eval _ opts _ =
+    let msg0 = "MEmptyT"
+        b = mempty @(PP t a)
+    in pure $ mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) []
+
+-- | similar to 'mempty'
+--
+-- >>> pz @(MEmptyT (SG.Sum Int)) ()
+-- PresentT (Sum {getSum = 0})
+--
+-- >>> pl @(MEmptyT _ ||| Ones Id) (Right "abc")
+-- Present ["a","b","c"] ((|||) Right ["a","b","c"] | "abc")
+-- PresentT ["a","b","c"]
+--
+-- >>> pl @(MEmptyT _ ||| Ones Id) (Left ["ab"])
+-- Present [] ((|||) Left [] | ["ab"])
+-- PresentT []
+--
+-- >>> pl @(MEmptyT (Maybe ())) 'x'
+-- Present Nothing (MEmptyT Nothing)
+-- PresentT Nothing
+--
+data MEmptyT (t :: Type)
+type MEmptyTT (t :: Type) = MEmptyT' (Hole t)
+
+instance P (MEmptyTT t) x => P (MEmptyT t) x where
+  type PP (MEmptyT t) x = PP (MEmptyTT t) x
+  eval _ = eval (Proxy @(MEmptyTT t))
+
+-- | creates a mempty value for the proxy
+--
+-- >>> pl @('Proxy >> MEmptyP) "abc"
+-- Present "" ((>>) "" | {MEmptyT ""})
+-- PresentT ""
+--
+data MEmptyP
+type MEmptyPT = MEmptyT' Unproxy -- expects a proxy: so only some things work with this: eg MaybeIn
+
+instance P MEmptyPT x => P MEmptyP x where
+  type PP MEmptyP x = PP MEmptyPT x
+  eval _ = eval (Proxy @MEmptyPT)
+
+-- | similar to 'SG.stimes'
+--
+-- >>> pz @(STimes 4 Id) (SG.Sum 3)
+-- PresentT (Sum {getSum = 12})
+--
+-- >>> pz @(STimes 4 Id) "ab"
+-- PresentT "abababab"
+--
+-- >>> pl @(STimes 4 Id) (SG.Sum 13)
+-- Present Sum {getSum = 52} (STimes 4 p=Sum {getSum = 13} Sum {getSum = 52} | n=4 | Sum {getSum = 13})
+-- PresentT (Sum {getSum = 52})
+--
+-- >>> pl @(STimes (Fst Id) (Snd Id)) (4,['x','y'])
+-- Present "xyxyxyxy" (STimes 4 p="xy" "xyxyxyxy" | n=4 | "xy")
+-- PresentT "xyxyxyxy"
+--
+-- >>> pl @(STimes (Fst Id) (Snd Id)) (4,"abc")
+-- Present "abcabcabcabc" (STimes 4 p="abc" "abcabcabcabc" | n=4 | "abc")
+-- PresentT "abcabcabcabc"
+--
+-- >>> pl @(STimes 4 Id) "abc"
+-- Present "abcabcabcabc" (STimes 4 p="abc" "abcabcabcabc" | n=4 | "abc")
+-- PresentT "abcabcabcabc"
+--
+
+data STimes n p
+instance (P n a
+        , Integral (PP n a)
+        , Semigroup (PP p a)
+        , P p a
+        , Show (PP p a)
+        ) => P (STimes n p) a where
+  type PP (STimes n p) a = PP p a
+  eval _ opts a = do
+    let msg0 = "STimes"
+    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (fromIntegral -> (n::Int),p,pp,qq) ->
+        let msg1 = msg0 <> " " <> showL opts n <> " p=" <> show p
+            b = SG.stimes n p
+            in mkNode opts (PresentT b) (show01' opts msg1 b "n=" n <> showVerbose opts " | " p) [hh pp, hh qq]
+ src/Predicate/Data/Numeric.hs view
@@ -0,0 +1,1068 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted numeric functions
+-}
+module Predicate.Data.Numeric (
+
+  -- ** numeric expressions
+    type (+)
+  , type (-)
+  , type (*)
+  , type (/)
+  , Negate
+  , Abs
+  , Signum
+  , FromInteger
+  , FromInteger'
+  , FromIntegral
+  , FromIntegral'
+  , Truncate
+  , Truncate'
+  , Ceiling
+  , Ceiling'
+  , Floor
+  , Floor'
+  , Even
+  , Odd
+  , Div
+  , Mod
+  , DivMod
+  , QuotRem
+  , Quot
+  , Rem
+  , LogBase
+  , type (^)
+  , type (**)
+
+  -- *** rational numbers
+  , type (%)
+  , type (-%)
+  , ToRational
+  , FromRational
+  , FromRational'
+
+ -- ** read / show expressions
+  , ReadBase
+  , ReadBase'
+  , ShowBase
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Ordering (type (==))
+import GHC.TypeLits (Nat,KnownNat)
+import qualified GHC.TypeLits as GL
+import Data.List
+import Data.Proxy
+import Data.Typeable
+import Data.Kind (Type)
+import Data.Maybe
+import qualified Numeric
+import Data.Char
+import Data.Ratio
+import GHC.Real (Ratio((:%)))
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+-- >>> import Data.Time
+
+data FromInteger' t n
+
+instance (Num (PP t a)
+        , Integral (PP n a)
+        , P n a
+        , Show (PP t a)
+        ) => P (FromInteger' t n) a where
+  type PP (FromInteger' t n) a = PP t a
+  eval _ opts a = do
+    let msg0 = "FromInteger"
+    nn <- eval (Proxy @n) opts a
+    pure $ case getValueLR opts msg0 nn [] of
+      Left e -> e
+      Right n ->
+        let b = fromInteger (fromIntegral n)
+        in mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) [hh nn]
+
+-- | 'fromInteger' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(FromInteger (SG.Sum _) Id) 23
+-- PresentT (Sum {getSum = 23})
+--
+-- >>> pz @(FromInteger Rational 44) 12
+-- PresentT (44 % 1)
+--
+-- >>> pz @(FromInteger Rational Id) 12
+-- PresentT (12 % 1)
+--
+-- >>> pl @((FromInteger _ 12 &&& Id) >> Fst Id + Snd Id) (SG.Min 7)
+-- Present Min {getMin = 19} ((>>) Min {getMin = 19} | {getMin = 19})
+-- PresentT (Min {getMin = 19})
+--
+-- >>> pl @((FromInteger _ 12 &&& Id) >> SapA) (SG.Product 7)
+-- Present Product {getProduct = 84} ((>>) Product {getProduct = 84} | {getProduct = 84})
+-- PresentT (Product {getProduct = 84})
+--
+-- >>> pl @(FromInteger (SG.Sum _) (Fst Id)) (3,"A")
+-- Present Sum {getSum = 3} (FromInteger Sum {getSum = 3})
+-- PresentT (Sum {getSum = 3})
+--
+-- >>> pl @(FromInteger DiffTime 123) 'x'
+-- Present 123s (FromInteger 123s)
+-- PresentT 123s
+--
+data FromInteger (t :: Type) p
+type FromIntegerT (t :: Type) p = FromInteger' (Hole t) p
+--type FromIntegerP n = FromInteger' Unproxy n
+
+instance P (FromIntegerT t p) x => P (FromInteger t p) x where
+  type PP (FromInteger t p) x = PP (FromIntegerT t p) x
+  eval _ = eval (Proxy @(FromIntegerT t p))
+
+-- | 'fromIntegral' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(FromIntegral (SG.Sum _) Id) 23
+-- PresentT (Sum {getSum = 23})
+data FromIntegral' t n
+
+instance (Num (PP t a)
+        , Integral (PP n a)
+        , P n a
+        , Show (PP t a)
+        , Show (PP n a)
+        ) => P (FromIntegral' t n) a where
+  type PP (FromIntegral' t n) a = PP t a
+  eval _ opts a = do
+    let msg0 = "FromIntegral"
+    nn <- eval (Proxy @n) opts a
+    pure $ case getValueLR opts msg0 nn [] of
+      Left e -> e
+      Right n ->
+        let b = fromIntegral n
+        in mkNode opts (PresentT b) (show01 opts msg0 b n) [hh nn]
+
+data FromIntegral (t :: Type) p
+type FromIntegralT (t :: Type) p = FromIntegral' (Hole t) p
+
+instance P (FromIntegralT t p) x => P (FromIntegral t p) x where
+  type PP (FromIntegral t p) x = PP (FromIntegralT t p) x
+  eval _ = eval (Proxy @(FromIntegralT t p))
+
+-- | 'toRational' function
+--
+-- >>> pz @(ToRational Id) 23.5
+-- PresentT (47 % 2)
+--
+-- >>> pl @((ToRational 123 &&& Id) >> Fst Id + Snd Id) 4.2
+-- Present 636 % 5 ((>>) 636 % 5 | {123 % 1 + 21 % 5 = 636 % 5})
+-- PresentT (636 % 5)
+--
+-- >>> pl @(Fst Id >= Snd Id || Snd Id > 23 || 12 -% 5 <= ToRational (Fst Id)) (12,13)
+-- True (False || True)
+-- TrueT
+--
+-- >>> pl @(ToRational 14) ()
+-- Present 14 % 1 (ToRational 14 % 1 | 14)
+-- PresentT (14 % 1)
+--
+-- >>> pl @(ToRational 5 / ToRational 3) 'x'
+-- Present 5 % 3 (5 % 1 / 3 % 1 = 5 % 3)
+-- PresentT (5 % 3)
+--
+
+data ToRational p
+
+instance (a ~ PP p x
+         , Show a
+         , Real a
+         , P p x)
+   => P (ToRational p) x where
+  type PP (ToRational p) x = Rational
+  eval _ opts x = do
+    let msg0 = "ToRational"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right a ->
+        let r = toRational a
+        in mkNode opts (PresentT r) (show01 opts msg0 r a) [hh pp]
+
+-- | 'fromRational' function where you need to provide the type \'t\' of the result
+--
+-- >>> pl @(FromRational' (Fst Id) (Snd Id)) (1::Float,2 % 5)
+-- Present 0.4 (FromRational 0.4 | 2 % 5)
+-- PresentT 0.4
+--
+data FromRational' t r
+
+instance (P r a
+        , PP r a ~ Rational
+        , Show (PP t a)
+        , Fractional (PP t a)
+        ) => P (FromRational' t r) a where
+  type PP (FromRational' t r) a = PP t a
+  eval _ opts a = do
+    let msg0 = "FromRational"
+    rr <- eval (Proxy @r) opts a
+    pure $ case getValueLR opts msg0 rr [] of
+      Left e -> e
+      Right r ->
+        let b = fromRational @(PP t a) r
+        in mkNode opts (PresentT b) (show01 opts msg0 b r) [hh rr]
+
+-- | 'fromRational' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(FromRational Rational Id) 23.5
+-- PresentT (47 % 2)
+--
+-- >>> pl @(FromRational Float (4 % 5)) ()
+-- Present 0.8 (FromRational 0.8 | 4 % 5)
+-- PresentT 0.8
+--
+data FromRational (t :: Type) p
+type FromRationalT (t :: Type) p = FromRational' (Hole t) p
+
+instance P (FromRationalT t p) x => P (FromRational t p) x where
+  type PP (FromRational t p) x = PP (FromRationalT t p) x
+  eval _ = eval (Proxy @(FromRationalT t p))
+
+-- | 'truncate' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(Truncate Int Id) (23 % 5)
+-- PresentT 4
+--
+-- >>> pl @(Truncate' (Fst Id >> Unproxy) (Snd Id)) (Proxy @Integer,2.3)
+-- Present 2 (Truncate 2 | 2.3)
+-- PresentT 2
+--
+-- >>> pl @(Truncate' (Fst Id) (Snd Id)) (1::Int,2.3)
+-- Present 2 (Truncate 2 | 2.3)
+-- PresentT 2
+--
+data Truncate' t p
+
+instance (Show (PP p x)
+        , P p x
+        , Show (PP t x)
+        , RealFrac (PP p x)
+        , Integral (PP t x)
+        ) => P (Truncate' t p) x where
+  type PP (Truncate' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "Truncate"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = truncate p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data Truncate (t :: Type) p
+type TruncateT (t :: Type) p = Truncate' (Hole t) p
+
+instance P (TruncateT t p) x => P (Truncate t p) x where
+  type PP (Truncate t p) x = PP (TruncateT t p) x
+  eval _ = eval (Proxy @(TruncateT t p))
+
+-- | 'ceiling' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(Ceiling Int Id) (23 % 5)
+-- PresentT 5
+data Ceiling' t p
+
+instance (Show (PP p x)
+        , P p x
+        , Show (PP t x)
+        , RealFrac (PP p x)
+        , Integral (PP t x)
+        ) => P (Ceiling' t p) x where
+  type PP (Ceiling' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "Ceiling"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = ceiling p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data Ceiling (t :: Type) p
+type CeilingT (t :: Type) p = Ceiling' (Hole t) p
+
+instance P (CeilingT t p) x => P (Ceiling t p) x where
+  type PP (Ceiling t p) x = PP (CeilingT t p) x
+  eval _ = eval (Proxy @(CeilingT t p))
+
+-- | 'floor' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(Floor Int Id) (23 % 5)
+-- PresentT 4
+data Floor' t p
+
+instance (Show (PP p x)
+        , P p x
+        , Show (PP t x)
+        , RealFrac (PP p x)
+        , Integral (PP t x)
+        ) => P (Floor' t p) x where
+  type PP (Floor' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "Floor"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = floor p
+        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
+
+data Floor (t :: Type) p
+type FloorT (t :: Type) p = Floor' (Hole t) p
+
+instance P (FloorT t p) x => P (Floor t p) x where
+  type PP (Floor t p) x = PP (FloorT t p) x
+  eval _ = eval (Proxy @(FloorT t p))
+
+data BinOp = BMult | BSub | BAdd deriving (Show,Eq)
+
+data p + q
+infixl 6 +
+
+type AddT p q = Bin 'BAdd p q
+
+instance P (AddT p q) x => P (p + q) x where
+  type PP (p + q) x = PP (AddT p q) x
+  eval _ = eval (Proxy @(AddT p q))
+
+data p - q
+infixl 6 -
+
+type SubT p q = Bin 'BSub p q
+
+instance P (SubT p q) x => P (p - q) x where
+  type PP (p - q) x = PP (SubT p q) x
+  eval _ = eval (Proxy @(SubT p q))
+
+data p * q
+infixl 7 *
+
+type MultT p q = Bin 'BMult p q
+
+instance P (MultT p q) x => P (p * q) x where
+  type PP (p * q) x = PP (MultT p q) x
+  eval _ = eval (Proxy @(MultT p q))
+
+-- | similar to 'GHC.Real.(^)'
+--
+-- >>> pz @(Fst Id ^ Snd Id) (10,4)
+-- PresentT 10000
+--
+data p ^ q
+infixr 8 ^
+
+instance (P p a
+        , P q a
+        , Show (PP p a)
+        , Show (PP q a)
+        , Num (PP p a)
+        , Integral (PP q a)
+        ) => P (p ^ q) a where
+  type PP (p ^ q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "Pow"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right p -> do
+        qq <- eval (Proxy @q) opts a
+        pure $ case getValueLR opts msg0 qq [hh pp] of
+          Left e -> e
+          Right q ->
+                let hhs = [hh pp, hh qq]
+                in if q < 0 then mkNode opts (FailT (msg0 <> " negative exponent")) "" hhs
+                   else let d = p ^ q
+                        in mkNode opts (PresentT d) (showL opts p <> " ^ " <> showL opts q <> " = " <> showL opts d) hhs
+
+-- | similar to 'GHC.Float.(**)'
+--
+-- >>> pz @(Fst Id ** Snd Id) (10,4)
+-- PresentT 10000.0
+--
+-- >>> pz @'(Prime Id,Id ^ 3,(FromIntegral _ Id) ** (FromRational _ (1 % 2))) 4
+-- PresentT (False,64,2.0)
+--
+data p ** q
+infixr 8 **
+
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Floating (PP p a)
+        , Ord (PP q a)
+        ) => P (p ** q) a where
+  type PP (p ** q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "Exp"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+         let hhs = [hh pp, hh qq]
+         in if q < 0 then mkNode opts (FailT (msg0 <> " negative exponent")) "" hhs
+            else if p == 0 && q == 0 then mkNode opts (FailT (msg0 <> " zero/zero")) "" hhs
+            else let d = p ** q
+                in mkNode opts (PresentT d) (showL opts p <> " ** " <> showL opts q <> " = " <> showL opts d) hhs
+
+-- | similar to 'logBase'
+--
+-- >>> pz @(Fst Id `LogBase` Snd Id >> Truncate Int Id) (10,12345)
+-- PresentT 4
+--
+data LogBase p q
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP q a)
+        , Floating (PP q a)
+        , Ord (PP p a)
+        ) => P (LogBase p q) a where
+  type PP (LogBase p q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "LogBase"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+         let hhs = [hh pp, hh qq]
+         in if p <= 0 then mkNode opts (FailT (msg0 <> " non-positive base")) "" hhs
+            else let d = logBase p q
+                 in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p <> " " <> showL opts q <> " = " <> showL opts d) hhs
+
+class GetBinOp (k :: BinOp) where
+  getBinOp :: (Num a, a ~ b) => (String, a -> b -> a)
+
+instance GetBinOp 'BMult where
+  getBinOp = ("*",(*))
+instance GetBinOp 'BSub where
+  getBinOp = ("-",(-))
+instance GetBinOp 'BAdd where
+  getBinOp = ("+",(+))
+
+-- | addition, multiplication and subtraction
+--
+-- >>> pz @(Fst Id * Snd Id) (13,5)
+-- PresentT 65
+--
+-- >>> pz @(Fst Id + 4 * Length (Snd Id) - 4) (3,"hello")
+-- PresentT 19
+--
+data Bin (op :: BinOp) p q
+
+instance (GetBinOp op
+        , PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Num (PP p a)
+        ) => P (Bin op p q) a where
+  type PP (Bin op p q) a = PP p a
+  eval _ opts a = do
+    let (s,f) = getBinOp @op
+    lr <- runPQ s (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = p `f` q
+        in mkNode opts (PresentT d) (showL opts p <> " " <> s <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
+
+-- | fractional division
+--
+-- >>> pz @(Fst Id / Snd Id) (13,2)
+-- PresentT 6.5
+--
+-- >>> pz @(ToRational 13 / Id) 0
+-- FailT "(/) zero denominator"
+--
+-- >>> pz @(12 % 7 / 14 % 5 + Id) 12.4
+-- PresentT (3188 % 245)
+--
+data p / q
+infixl 7 /
+
+instance (PP p a ~ PP q a
+        , Eq (PP q a)
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Fractional (PP p a)
+        ) => P (p / q) a where
+  type PP (p / q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "(/)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq)
+         | q == 0 -> let msg1 = msg0 <> " zero denominator"
+                     in mkNode opts (FailT msg1) "" [hh pp, hh qq]
+         | otherwise ->
+            let d = p / q
+            in mkNode opts (PresentT d) (showL opts p <> " / " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
+
+-- | creates a 'Rational' value
+--
+-- >>> pz @(Id < 21 % 5) (-3.1)
+-- TrueT
+--
+-- >>> pz @(Id < 21 % 5) 4.5
+-- FalseT
+--
+-- >>> pz @(Fst Id % Snd Id) (13,2)
+-- PresentT (13 % 2)
+--
+-- >>> pz @(13 % Id) 0
+-- FailT "(%) zero denominator"
+--
+-- >>> pz @(4 % 3 + 5 % 7) "asfd"
+-- PresentT (43 % 21)
+--
+-- >>> pz @(4 -% 7 * 5 -% 3) "asfd"
+-- PresentT (20 % 21)
+--
+-- >>> pz @(Negate (14 % 3)) ()
+-- PresentT ((-14) % 3)
+--
+-- >>> pz @(14 % 3) ()
+-- PresentT (14 % 3)
+--
+-- >>> pz @(Negate (14 % 3) ==! FromIntegral _ (Negate 5)) ()
+-- PresentT GT
+--
+-- >>> pz @(14 -% 3 ==! 5 -% 1) "aa"
+-- PresentT GT
+--
+-- >>> pz @(Negate (14 % 3) ==! Negate 5 % 2) ()
+-- PresentT LT
+--
+-- >>> pz @(14 -% 3 * 5 -% 1) ()
+-- PresentT (70 % 3)
+--
+-- >>> pz @(14 % 3 ==! 5 % 1) ()
+-- PresentT LT
+--
+-- >>> pz @(15 % 3 / 4 % 2) ()
+-- PresentT (5 % 2)
+--
+data p % q
+infixl 8 %
+
+instance (Integral (PP p x)
+        , Integral (PP q x)
+        , Eq (PP q x)
+        , P p x
+        , P q x
+        , Show (PP p x)
+        , Show (PP q x)
+        ) => P (p % q) x where
+  type PP (p % q) x = Rational
+  eval _ opts x = do
+    let msg0 = "(%)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq)
+         | q == 0 -> let msg1 = msg0 <> " zero denominator"
+                     in mkNode opts (FailT msg1) "" [hh pp, hh qq]
+         | otherwise ->
+            let z@(p1,q1) = (fromIntegral p, fromIntegral q)
+                d@(dn :% dd) = uncurry (%) z
+                zz = if dn == p1 && dd == q1 then ""
+                     else litVerbose opts " | " (show p <> " % " <> show q)
+            in mkNode opts (PresentT d) (showL opts d <> zz) [hh pp, hh qq]
+
+-- | negate a ratio
+--
+-- >>> pl @'[1 % 1 ,3 -% 2,3 -% 1] ()
+-- Present [1 % 1,(-3) % 2,(-3) % 1] ('[1 % 1,(-3) % 2,(-3) % 1] (1 % 1) | ())
+-- PresentT [1 % 1,(-3) % 2,(-3) % 1]
+--
+-- >>> pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Floor _ Id) Id) ()
+-- Present [1,-5,5,-1] ((>>) [1,-5,5,-1] | {Map [1,-5,5,-1] | [1 % 1,(-33) % 7,21 % 4,(-1) % 1]})
+-- PresentT [1,-5,5,-1]
+--
+-- >>> pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Ceiling _ Id) Id) ()
+-- Present [1,-4,6,-1] ((>>) [1,-4,6,-1] | {Map [1,-4,6,-1] | [1 % 1,(-33) % 7,21 % 4,(-1) % 1]})
+-- PresentT [1,-4,6,-1]
+--
+-- >>> pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Truncate _ Id) Id) ()
+-- Present [1,-4,5,-1] ((>>) [1,-4,5,-1] | {Map [1,-4,5,-1] | [1 % 1,(-33) % 7,21 % 4,(-1) % 1]})
+-- PresentT [1,-4,5,-1]
+--
+-- >>> pl @(5 % 1 / 3 -% 1) 'x'
+-- Present (-5) % 3 (5 % 1 / (-3) % 1 = (-5) % 3)
+-- PresentT ((-5) % 3)
+--
+-- >>> pl @(5 -% 1 / Fst Id) (3,'x')
+-- Present (-5) % 3 ((-5) % 1 / 3 % 1 = (-5) % 3)
+-- PresentT ((-5) % 3)
+--
+data p -% q -- = Negate (p % q)
+infixl 8 -%
+type NegateRatioT p q = Negate (p % q)
+
+instance P (NegateRatioT p q) x => P (p -% q) x where
+  type PP (p -% q) x = PP (NegateRatioT p q) x
+  eval _ = eval (Proxy @(NegateRatioT p q))
+
+
+-- | similar to 'negate'
+--
+-- >>> pz @(Negate Id) 14
+-- PresentT (-14)
+--
+-- >>> pz @(Negate (Fst Id * Snd Id)) (14,3)
+-- PresentT (-42)
+--
+-- >>> pz @(Negate (15 -% 4)) "abc"
+-- PresentT (15 % 4)
+--
+-- >>> pz @(Negate (15 % 3)) ()
+-- PresentT ((-5) % 1)
+--
+-- >>> pz @(Negate (Fst Id % Snd Id)) (14,3)
+-- PresentT ((-14) % 3)
+--
+data Negate p
+
+instance ( Show (PP p x)
+         , Num (PP p x)
+         , P p x
+         ) => P (Negate p) x where
+  type PP (Negate p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Negate"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = negate p
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+
+-- | similar to 'abs'
+--
+-- >>> pz @(Abs Id) (-14)
+-- PresentT 14
+--
+-- >>> pz @(Abs (Snd Id)) ("xx",14)
+-- PresentT 14
+--
+-- >>> pz @(Abs Id) 0
+-- PresentT 0
+--
+-- >>> pz @(Abs (Negate 44)) "aaa"
+-- PresentT 44
+--
+data Abs p
+
+instance ( Show (PP p x)
+         , Num (PP p x)
+         , P p x
+         ) => P (Abs p) x where
+  type PP (Abs p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Abs"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = abs p
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+-- | similar to 'div'
+--
+-- >>> pz @(Div (Fst Id) (Snd Id)) (10,4)
+-- PresentT 2
+--
+-- >>> pz @(Div (Fst Id) (Snd Id)) (10,0)
+-- FailT "Div zero denominator"
+--
+data Div p q
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Integral (PP p a)
+        ) => P (Div p q) a where
+  type PP (Div p q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "Div"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+         let hhs = [hh pp, hh qq]
+         in case q of
+              0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
+              _ -> let d = p `div` q
+                   in mkNode opts (PresentT d) (showL opts p <> " `div` " <> showL opts q <> " = " <> showL opts d) hhs
+
+
+-- | similar to 'GHC.Real.mod'
+--
+-- >>> pz @(Mod (Fst Id) (Snd Id)) (10,3)
+-- PresentT 1
+--
+-- >>> pz @(Mod (Fst Id) (Snd Id)) (10,0)
+-- FailT "Mod zero denominator"
+--
+data Mod p q
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Integral (PP p a)
+        ) => P (Mod p q) a where
+  type PP (Mod p q) a = PP p a
+  eval _ opts a = do
+    let msg0 = "Mod"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+         let hhs = [hh pp, hh qq]
+         in case q of
+              0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
+              _ -> let d = p `mod` q
+                   in mkNode opts (PresentT d) (showL opts p <> " `mod` " <> showL opts q <> " = " <> showL opts d) hhs
+
+-- | similar to 'divMod'
+--
+-- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,3)
+-- PresentT (3,1)
+--
+-- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,-3)
+-- PresentT (-4,-2)
+--
+-- >>> pz @(DivMod (Fst Id) (Snd Id)) (-10,3)
+-- PresentT (-4,2)
+--
+-- >>> pz @(DivMod (Fst Id) (Snd Id)) (-10,-3)
+-- PresentT (3,-1)
+--
+-- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,0)
+-- FailT "DivMod zero denominator"
+--
+-- >>> pl @(DivMod (Negate Id) 7) 23
+-- Present (-4,5) (-23 `divMod` 7 = (-4,5))
+-- PresentT (-4,5)
+--
+-- >>> pl @(DivMod (Fst Id) (Snd Id)) (10,-3)
+-- Present (-4,-2) (10 `divMod` -3 = (-4,-2))
+-- PresentT (-4,-2)
+--
+-- >>> pl @(DivMod (Fst Id) (Snd Id)) (10,0)
+-- Error DivMod zero denominator
+-- FailT "DivMod zero denominator"
+--
+-- >>> pl @(DivMod (9 - Fst Id) (Last (Snd Id))) (10,[12,13])
+-- Present (-1,12) (-1 `divMod` 13 = (-1,12))
+-- PresentT (-1,12)
+--
+
+data DivMod p q
+
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Integral (PP p a)
+        ) => P (DivMod p q) a where
+  type PP (DivMod p q) a = (PP p a, PP p a)
+  eval _ opts a = do
+    let msg0 = "DivMod"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+        in case q of
+             0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
+             _ -> let d = p `divMod` q
+                  in mkNode opts (PresentT d) (showL opts p <> " `divMod` " <> showL opts q <> " = " <> showL opts d) hhs
+
+-- | similar to 'quotRem'
+--
+-- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,3)
+-- PresentT (3,1)
+--
+-- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,-3)
+-- PresentT (-3,1)
+--
+-- >>> pz @(QuotRem (Fst Id) (Snd Id)) (-10,-3)
+-- PresentT (3,-1)
+--
+-- >>> pz @(QuotRem (Fst Id) (Snd Id)) (-10,3)
+-- PresentT (-3,-1)
+--
+-- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,0)
+-- FailT "QuotRem zero denominator"
+--
+-- >>> pl @(QuotRem (Negate Id) 7) 23
+-- Present (-3,-2) (-23 `quotRem` 7 = (-3,-2))
+-- PresentT (-3,-2)
+--
+-- >>> pl @(QuotRem (Fst Id) (Snd Id)) (10,-3)
+-- Present (-3,1) (10 `quotRem` -3 = (-3,1))
+-- PresentT (-3,1)
+--
+
+data QuotRem p q
+
+instance (PP p a ~ PP q a
+        , P p a
+        , P q a
+        , Show (PP p a)
+        , Integral (PP p a)
+        ) => P (QuotRem p q) a where
+  type PP (QuotRem p q) a = (PP p a, PP p a)
+  eval _ opts a = do
+    let msg0 = "QuotRem"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+        in case q of
+             0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
+             _ -> let d = p `quotRem` q
+                  in mkNode opts (PresentT d) (showL opts p <> " `quotRem` " <> showL opts q <> " = " <> showL opts d) hhs
+
+data Quot p q
+type QuotT p q = Fst (QuotRem p q)
+
+instance P (QuotT p q) x => P (Quot p q) x where
+  type PP (Quot p q) x = PP (QuotT p q) x
+  eval _ = eval (Proxy @(QuotT p q))
+
+data Rem p q
+type RemT p q = Snd (QuotRem p q)
+
+instance P (RemT p q) x => P (Rem p q) x where
+  type PP (Rem p q) x = PP (RemT p q) x
+  eval _ = eval (Proxy @(RemT p q))
+
+-- | similar to 'even'
+--
+-- >>> pz @(Map Even Id) [9,-4,12,1,2,3]
+-- PresentT [False,True,True,False,True,False]
+--
+-- >>> pz @(Map '(Even,Odd) Id) [9,-4,12,1,2,3]
+-- PresentT [(False,True),(True,False),(True,False),(False,True),(True,False),(False,True)]
+--
+data Even
+type EvenT = Mod I 2 == 0
+
+instance P EvenT x => P Even x where
+  type PP Even x = Bool
+  eval _ = evalBool (Proxy @EvenT)
+
+data Odd
+type OddT = Mod I 2 == 1
+
+instance P OddT x => P Odd x where
+  type PP Odd x = Bool
+  eval _ = evalBool (Proxy @OddT)
+
+-- | similar to 'signum'
+--
+-- >>> pz @(Signum Id) (-14)
+-- PresentT (-1)
+--
+-- >>> pz @(Signum Id) 14
+-- PresentT 1
+--
+-- >>> pz @(Signum Id) 0
+-- PresentT 0
+--
+data Signum p
+
+instance ( Show (PP p x)
+         , Num (PP p x)
+         , P p x
+         ) => P (Signum p) x where
+  type PP (Signum p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Signum"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = signum p
+        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
+
+-- supports negative numbers unlike readInt
+data ReadBase' t (n :: Nat) p
+
+instance (Typeable (PP t x)
+        , ZwischenT 2 36 n
+        , Show (PP t x)
+        , Num (PP t x)
+        , KnownNat n
+        , PP p x ~ String
+        , P p x
+        ) => P (ReadBase' t n p) x where
+  type PP (ReadBase' t n p) x = PP t x
+  eval _ opts x = do
+    let n = nat @n
+        xs = getValidBase n
+        msg0 = "ReadBase(" <> t <> "," <> show n <> ")"
+        t = showT @(PP t x)
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (ff,p1) = case p of
+                        '-':q -> (negate,q)
+                        _ -> (id,p)
+        in case Numeric.readInt (fromIntegral n)
+            ((`elem` xs) . toLower)
+            (fromJust . (`elemIndex` xs) . toLower)
+            p1 of
+             [(b,"")] -> mkNode opts (PresentT (ff b)) (msg0 <> " " <> showL opts (ff b) <> showVerbose opts " | " p) [hh pp]
+             o -> mkNode opts (FailT ("invalid base " <> show n)) (msg0 <> " as=" <> p <> " err=" <> showL opts o) [hh pp]
+
+-- | Read a number using base 2 through a maximum of 36
+--
+-- >>> pz @(ReadBase Int 16 Id) "00feD"
+-- PresentT 4077
+--
+-- >>> pz @(ReadBase Int 16 Id) "-ff"
+-- PresentT (-255)
+--
+-- >>> pz @(ReadBase Int 2 Id) "10010011"
+-- PresentT 147
+--
+-- >>> pz @(ReadBase Int 8 Id) "Abff"
+-- FailT "invalid base 8"
+--
+-- >>> pl @(ReadBase Int 16 Id >> GuardSimple (Id > 0xffff) >> ShowBase 16 Id) "12344"
+-- Present "12344" ((>>) "12344" | {ShowBase(16) 12344 | 74564})
+-- PresentT "12344"
+--
+-- >>> :set -XBinaryLiterals
+-- >>> pz @(ReadBase Int 16 Id >> GuardSimple (Id > 0b10011111) >> ShowBase 16 Id) "7f"
+-- FailT "(127 > 159)"
+--
+-- >>> pl @(ReadBase Int 16 Id) "fFe0"
+-- Present 65504 (ReadBase(Int,16) 65504 | "fFe0")
+-- PresentT 65504
+--
+-- >>> pl @(ReadBase Int 16 Id) "-ff"
+-- Present -255 (ReadBase(Int,16) -255 | "-ff")
+-- PresentT (-255)
+--
+-- >>> pl @(ReadBase Int 16 Id) "ff"
+-- Present 255 (ReadBase(Int,16) 255 | "ff")
+-- PresentT 255
+--
+-- >>> pl @(ReadBase Int 22 Id) "zzz"
+-- Error invalid base 22 (ReadBase(Int,22) as=zzz err=[])
+-- FailT "invalid base 22"
+--
+-- >>> pl @((ReadBase Int 16 Id &&& Id) >> First (ShowBase 16 Id)) "fFe0"
+-- Present ("ffe0","fFe0") ((>>) ("ffe0","fFe0") | {(***) ("ffe0","fFe0") | (65504,"fFe0")})
+-- PresentT ("ffe0","fFe0")
+--
+-- >>> pl @(ReadBase Int 2 Id) "101111"
+-- Present 47 (ReadBase(Int,2) 47 | "101111")
+-- PresentT 47
+--
+data ReadBase (t :: Type) (n :: Nat) p
+type ReadBaseT (t :: Type) (n :: Nat) p = ReadBase' (Hole t) n p
+
+instance P (ReadBaseT t n p) x => P (ReadBase t n p) x where
+  type PP (ReadBase t n p) x = PP (ReadBaseT t n p) x
+  eval _ = eval (Proxy @(ReadBaseT t n p))
+
+getValidBase :: Int -> String
+getValidBase n =
+  let xs = ['0'..'9'] <> ['a'..'z']
+      len = length xs
+  in if n > len || n < 2 then errorInProgram $ "getValidBase: oops invalid base valid is 2 thru " ++ show len ++ " found " ++ show n
+     else take n xs
+
+-- | Display a number at base 2 to 36, similar to 'Numeric.showIntAtBase' but supports signed numbers
+--
+-- >>> pz @(ShowBase 16 Id) 4077
+-- PresentT "fed"
+--
+-- >>> pz @(ShowBase 16 Id) (-255)
+-- PresentT "-ff"
+--
+-- >>> pz @(ShowBase 2 Id) 147
+-- PresentT "10010011"
+--
+-- >>> pz @(ShowBase 2 (Negate 147)) "whatever"
+-- PresentT "-10010011"
+--
+-- >>> pl @(ShowBase 16 Id) (-123)
+-- Present "-7b" (ShowBase(16) -7b | -123)
+-- PresentT "-7b"
+--
+-- >>> pl @(ShowBase 16 Id) 123
+-- Present "7b" (ShowBase(16) 7b | 123)
+-- PresentT "7b"
+--
+-- >>> pl @(ShowBase 16 Id) 65504
+-- Present "ffe0" (ShowBase(16) ffe0 | 65504)
+-- PresentT "ffe0"
+--
+
+data ShowBase (n :: Nat) p
+
+instance (PP p x ~ a
+        , P p x
+        , Show a
+        , 2 GL.<= n
+        , n GL.<= 36
+        , KnownNat n
+        , Integral a
+        ) => P (ShowBase n p) x where
+  type PP (ShowBase n p) x = String
+  eval _ opts x = do
+    let n = nat @n
+        xs = getValidBase n
+        msg0 = "ShowBase(" <> show n <> ")"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (ff,a') = if p < 0 then (('-':), abs p) else (id,p)
+            b = Numeric.showIntAtBase (fromIntegral n) (xs !!) a' ""
+        in mkNode opts (PresentT (ff b)) (msg0 <> " " <> litL opts (ff b) <> showVerbose opts " | " p) [hh pp]
+ src/Predicate/Data/Ordering.hs view
@@ -0,0 +1,598 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted 'Ordering' functions
+-}
+module Predicate.Data.Ordering (
+
+ -- ** compare expressions
+    type (>)
+  , type (>=)
+  , type (==)
+  , type (/=)
+  , type (<=)
+  , type (<)
+  , type (>~)
+  , type (>=~)
+  , type (==~)
+  , type (/=~)
+  , type (<=~)
+  , type (<~)
+  , Gt
+  , Ge
+  , Same
+  , Le
+  , Lt
+  , Ne
+  , type (==!)
+  , OrdP
+  , OrdA'
+  , OrdA
+  , OrdI
+  , type (===~)
+  , Cmp
+  , CmpI
+
+  , Asc
+  , Asc'
+  , Desc
+  , Desc'
+  , AllPositive
+  , Positive
+  , AllNegative
+  , Negative
+
+  , Ands
+  , Ors
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Tuple (Pairs)
+import Data.Proxy
+import Data.Char
+import Data.Function
+import Data.Foldable (toList)
+import Data.List (findIndex)
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+
+-- | compare if expression \'p\' is greater than \'q\'
+--
+-- >>> pl @(Gt 4) 5
+-- True (5 > 4)
+-- TrueT
+--
+type Gt n = I > n
+type Ge n = I >= n
+type Same n = I == n
+type Le n = I <= n
+type Lt n = I < n
+type Ne n = I /= n
+
+-- | compare if expression \'p\' is greater than \'q\'
+--
+-- >>> pl @(Id > "xx") "abc"
+-- False ("abc" > "xx")
+-- FalseT
+--
+-- >>> pl @(Id > "aa") "abc"
+-- True ("abc" > "aa")
+-- TrueT
+--
+-- >>> pl @(Fst Id > Snd Id) (True,False)
+-- True (True > False)
+-- TrueT
+--
+data p > q
+infix 4 >
+
+instance P (Cmp 'CGt p q) x => P (p > q) x where
+  type PP (p > q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CGt p q))
+
+-- | compare if expression \'p\' is greater than or equal to \'q\'
+data p >= q
+infix 4 >=
+
+instance P (Cmp 'CGe p q) x => P (p >= q) x where
+  type PP (p >= q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CGe p q))
+
+-- | compare if expression \'p\' is equal to \'q\'
+--
+-- >>> pl @(Fst Id == Snd Id) ("ab","xyzabw")
+-- False ("ab" == "xyzabw")
+-- FalseT
+--
+-- >>> pl @(Fst Id == Snd Id) ("aBc","AbC")
+-- False ("aBc" == "AbC")
+-- FalseT
+--
+-- >>> pz @(Fst Id == Snd Id) ("aBc","aBc")
+-- TrueT
+--
+-- >>> pl @(Id == "Abc") "abc"
+-- False ("abc" == "Abc")
+-- FalseT
+--
+-- >>> pl @(Fst Id == Snd Id) (True,False)
+-- False (True == False)
+-- FalseT
+--
+-- >>> pl @(Not Id *** Id >> Fst Id == Snd Id) (True,False)
+-- True ((>>) True | {False == False})
+-- TrueT
+--
+data p == q
+infix 4 ==
+
+instance P (Cmp 'CEq p q) x => P (p == q) x where
+  type PP (p == q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CEq p q))
+
+-- | compare if expression \'p\' is less than or equal to \'q\'
+--
+-- >>> pl @(Not (Fst Id >> Len <= 6)) ([2..7],True)
+-- False (Not ((>>) True | {6 <= 6}))
+-- FalseT
+--
+-- >>> pl @(Fst Id >> Len <= 6) ([2..7],True)
+-- True ((>>) True | {6 <= 6})
+-- TrueT
+--
+-- >>> pl @(Length (Fst Id) <= 6) ([2..7],True)
+-- True (6 <= 6)
+-- TrueT
+--
+-- >>> pl @(Fst Id >> (Len <= 6)) ([2..7],True)
+-- True ((>>) True | {6 <= 6})
+-- TrueT
+--
+data p <= q
+infix 4 <=
+
+instance P (Cmp 'CLe p q) x => P (p <= q) x where
+  type PP (p <= q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CLe p q))
+
+-- | compare if expression \'p\' is less than \'q\'
+data p < q
+infix 4 <
+
+instance P (Cmp 'CLt p q) x => P (p < q) x where
+  type PP (p < q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CLt p q))
+
+-- | compare if expression \'p\' is not equal to \'q\'
+--
+-- >>> pl @(Fst Id /= Snd Id) ("ab","xyzabw")
+-- True ("ab" /= "xyzabw")
+-- TrueT
+--
+data p /= q
+infix 4 /=
+
+instance P (Cmp 'CNe p q) x => P (p /= q) x where
+  type PP (p /= q) x = Bool
+  eval _ = evalBool (Proxy @(Cmp 'CNe p q))
+
+-- | case-insensitive compare if string expression \'p\' is greater than \'q\'
+--
+data p >~ q
+infix 4 >~
+
+instance P (CmpI 'CGt p q) x => P (p >~ q) x where
+  type PP (p >~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CGt p q))
+
+-- | case-insensitive compare if string expression \'p\' is greater than or equal to \'q\'
+data p >=~ q
+infix 4 >=~
+
+instance P (CmpI 'CGe p q) x => P (p >=~ q) x where
+  type PP (p >=~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CGe p q))
+
+-- | case-insensitive compare if string expression \'p\' is equal to \'q\'
+data p ==~ q
+infix 4 ==~
+
+instance P (CmpI 'CEq p q) x => P (p ==~ q) x where
+  type PP (p ==~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CEq p q))
+
+-- | case-insensitive compare if string expression \'p\' is less than or equal to \'q\'
+data p <=~ q
+infix 4 <=~
+
+instance P (CmpI 'CLe p q) x => P (p <=~ q) x where
+  type PP (p <=~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CLe p q))
+
+-- | case-insensitive compare if string expression \'p\' is less than \'q\'
+data p <~ q
+infix 4 <~
+
+instance P (CmpI 'CLt p q) x => P (p <~ q) x where
+  type PP (p <~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CLt p q))
+
+-- | case-insensitive compare if string expression \'p\' is not equal to \'q\'
+data p /=~ q
+infix 4 /=~
+
+instance P (CmpI 'CNe p q) x => P (p /=~ q) x where
+  type PP (p /=~ q) x = Bool
+  eval _ = evalBool (Proxy @(CmpI 'CNe p q))
+
+
+-- | similar to 'compare'
+--
+-- >>> pz @(Fst Id ==! Snd Id) (10,9)
+-- PresentT GT
+--
+-- >>> pz @(14 % 3 ==! Fst Id -% Snd Id) (-10,7)
+-- PresentT GT
+--
+-- >>> pz @(Fst Id ==! Snd Id) (10,11)
+-- PresentT LT
+--
+-- >>> pz @(Snd Id ==! (Fst Id >> Snd Id >> Head Id)) (('x',[10,12,13]),10)
+-- PresentT EQ
+--
+-- >>> pz @(Snd Id ==! Head (Snd (Fst Id))) (('x',[10,12,13]),10)
+-- PresentT EQ
+--
+-- >>> pl @("aa" ==! Id) "aaaa"
+-- Present LT ((==!) "aa" < "aaaa")
+-- PresentT LT
+--
+-- >>> pl @(Pairs >> Map (First (Succ Id >> Succ Id) >> Fst Id ==! Snd Id) Id) [1,2,3,6,8]
+-- Present [GT,GT,LT,EQ] ((>>) [GT,GT,LT,EQ] | {Map [GT,GT,LT,EQ] | [(1,2),(2,3),(3,6),(6,8)]})
+-- PresentT [GT,GT,LT,EQ]
+--
+-- >>> pl @((Ones Id << ShowP Id) >> Map (Fst Id ==! Snd Id) Pairs) 1234223
+-- Present [LT,LT,LT,GT,EQ,LT] ((>>) [LT,LT,LT,GT,EQ,LT] | {Map [LT,LT,LT,GT,EQ,LT] | [("1","2"),("2","3"),("3","4"),("4","2"),("2","2"),("2","3")]})
+-- PresentT [LT,LT,LT,GT,EQ,LT]
+--
+-- >>> pl @("Abc" ==! Id) "abc"
+-- Present LT ((==!) "Abc" < "abc")
+-- PresentT LT
+--
+-- >>> pl @(Fst Id ==! Snd Id) (3,12)
+-- Present LT ((==!) 3 < 12)
+-- PresentT LT
+--
+-- >>> pl @(Fst Id ==! Snd Id) ("aBc","AbC")
+-- Present GT ((==!) "aBc" > "AbC")
+-- PresentT GT
+--
+-- >>> pl @(Snd Id ==! Fst Id) ("aBc","AbC")
+-- Present LT ((==!) "AbC" < "aBc")
+-- PresentT LT
+--
+
+data p ==! q
+infix 4 ==!
+
+type OrdP p q = p ==! q
+
+instance (Ord (PP p a)
+        , PP p a ~ PP q a
+        , P p a
+        , Show (PP q a)
+        , P q a
+        ) => P (p ==! q) a where
+  type PP (p ==! q) a = Ordering
+  eval _ opts a = do
+    let msg0 = "(==!)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = compare p q
+        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p <> " " <> prettyOrd d <> " " <> showL opts q) [hh pp, hh qq]
+
+-- | similar to 'compare' but using a tuple as input
+data OrdA p
+
+instance P (OrdA' p p) x => P (OrdA p) x where
+  type PP (OrdA p) x = PP (OrdA' p p) x
+  eval _ = eval (Proxy @(OrdA' p p))
+
+data OrdA' p q
+type OrdAT' p q = (Fst Id >> p) ==! (Snd Id >> q)
+
+instance P (OrdAT' p q) x => P (OrdA' p q) x where
+  type PP (OrdA' p q) x = PP (OrdAT' p q) x
+  eval _ = eval (Proxy @(OrdAT' p q))
+
+-- | compare two strings ignoring case and return an ordering
+--
+-- >>> pz @(Fst Id ===~ Snd Id) ("abC","aBc")
+-- PresentT EQ
+--
+-- >>> pz @(Fst Id ===~ Snd Id) ("abC","DaBc")
+-- PresentT LT
+--
+-- >>> pl @(Fst Id ===~ Snd Id &&& Fst Id ==! Snd Id) ("abc","abc")
+-- Present (EQ,EQ) (W '(EQ,EQ))
+-- PresentT (EQ,EQ)
+--
+--
+-- >>> pl @(Fst Id ===~ Snd Id) ("aBc","AbC")
+-- Present EQ ((===~) aBc = AbC)
+-- PresentT EQ
+--
+-- >>> pl @("Abc" ===~ Id) "abc"
+-- Present EQ ((===~) Abc = abc)
+-- PresentT EQ
+--
+--
+-- >>> pl @("Abc" ==~ Id) "abc"
+-- True (Abc ==~ abc)
+-- TrueT
+--
+-- >>> pl @(Fst Id ==~ Snd Id) ("aBc","AbC")
+-- True (aBc ==~ AbC)
+-- TrueT
+--
+-- >>> pl @(Fst Id ==~ Snd Id && Fst Id == Snd Id) ("Abc","Abc")
+-- True (True && True)
+-- TrueT
+--
+
+type OrdI p q = p ===~ q
+data p ===~ q
+infix 4 ===~
+
+instance (PP p a ~ String
+        , PP p a ~ PP q a
+        , P p a
+        , P q a
+        ) => P (p ===~ q) a where
+  type PP (p ===~ q) a = Ordering
+  eval _ opts a = do
+    let msg0 = "(===~)"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = on compare (map toLower) p q
+        in mkNode opts (PresentT d) (msg0 <> " " <> p <> " " <> prettyOrd d <> " " <> q) [hh pp, hh qq]
+
+-- | compare two values using the given ordering \'o\'
+--
+-- >>> pl @(Lt 4) 123
+-- False (123 < 4)
+-- FalseT
+--
+-- >>> pl @(Lt 4) 1
+-- True (1 < 4)
+-- TrueT
+--
+-- >>> pl @(Negate 7 <..> 20) (-4)
+-- True (-7 <= -4 <= 20)
+-- TrueT
+--
+-- >>> pl @(Negate 7 <..> 20) 21
+-- False (21 <= 20)
+-- FalseT
+--
+data Cmp (o :: OrderingP) p q
+
+instance (GetOrd o
+        , Ord (PP p a)
+        , Show (PP p a)
+        , PP p a ~ PP q a
+        , P p a
+        , P q a
+        ) => P (Cmp o p q) a where
+  type PP (Cmp o p q) a = Bool
+  eval _ opts a = do
+    let (sfn, fn) = getOrd @o
+    lr <- runPQ sfn (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = fn p q
+        in mkNodeB opts b (showL opts p <> " " <> sfn <> " " <> showL opts q) [hh pp, hh qq]
+
+-- | compare two strings ignoring case using the given ordering \'o\'
+data CmpI (o :: OrderingP) p q
+
+instance (PP p a ~ String
+        , GetOrd o
+        , PP p a ~ PP q a
+        , P p a
+        , P q a
+        ) => P (CmpI o p q) a where
+  type PP (CmpI o p q) a = Bool
+  eval _ opts a = do
+    let (sfn, fn) = getOrd @o
+    lr <- runPQ sfn (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let b = on fn (map toLower) p q
+        in mkNodeB opts b (p <> " " <> sfn <> "~ " <> q) [hh pp, hh qq]
+
+
+-- | a type level predicate for a monotonic increasing list
+--
+-- >>> pl @Asc "aaacdef"
+-- True (All(6))
+-- TrueT
+--
+-- >>> pz @Asc [1,2,3,4,5,5,7]
+-- TrueT
+--
+-- >>> pz @Asc "axacdef"
+-- FalseT
+--
+data Asc
+type AscT = All (Fst Id <= Snd Id) Pairs
+
+instance P AscT x => P Asc x where
+  type PP Asc x = PP AscT x
+  eval _ = evalBool (Proxy @AscT)
+
+-- | a type level predicate for a strictly increasing list
+--
+-- >>> pz @Asc' [1,2,3,4,5,5,7]
+-- FalseT
+--
+data Asc'
+type AscT' = All (Fst Id < Snd Id) Pairs
+
+instance P AscT' x => P Asc' x where
+  type PP Asc' x = PP AscT' x
+  eval _ = evalBool (Proxy @AscT')
+
+-- | a type level predicate for a monotonic decreasing list
+data Desc
+type DescT = All (Fst Id >= Snd Id) Pairs
+
+instance P DescT x => P Desc x where
+  type PP Desc x = PP DescT x
+  eval _ = evalBool (Proxy @DescT)
+-- | a type level predicate for a strictly decreasing list
+data Desc'
+type DescT' = All (Fst Id > Snd Id) Pairs
+
+instance P DescT' x => P Desc' x where
+  type PP Desc' x = PP DescT' x
+  eval _ = evalBool (Proxy @DescT')
+
+
+--type AscAlt = SortOn Id Id == Id
+--type DescAlt = SortOnDesc Id Id == Id
+
+-- | a type level predicate for all positive elements in a list
+--
+-- >>> pz @AllPositive [1,5,10,2,3]
+-- TrueT
+--
+-- >>> pz @AllPositive [0,1,5,10,2,3]
+-- FalseT
+--
+-- >>> pz @AllPositive [3,1,-5,10,2,3]
+-- FalseT
+--
+data AllPositive
+type AllPositiveT = All Positive Id
+
+instance P AllPositiveT x => P AllPositive x where
+  type PP AllPositive x = PP AllPositiveT x
+  eval _ = evalBool (Proxy @AllPositiveT)
+
+-- | a type level predicate for all negative elements in a list
+--
+-- >>> pz @AllNegative [-1,-5,-10,-2,-3]
+-- TrueT
+--
+data AllNegative
+type AllNegativeT = All Negative Id
+
+instance P AllNegativeT x => P AllNegative x where
+  type PP AllNegative x = PP AllNegativeT x
+  eval _ = evalBool (Proxy @AllNegativeT)
+
+
+type Positive = Gt 0
+
+type Negative = Lt 0
+
+-- | similar to 'Data.Foldable.and'
+--
+-- >>> pz @(Ands Id) [True,True,True]
+-- TrueT
+--
+-- >>> pl @(Ands Id) [True,True,True,False]
+-- False (Ands(4) i=3 | [True,True,True,False])
+-- FalseT
+--
+-- >>> pz @(Ands Id) []
+-- TrueT
+--
+data Ands p
+
+instance (PP p x ~ t a
+        , P p x
+        , Show (t a)
+        , Foldable t
+        , a ~ Bool
+        ) => P (Ands p) x where
+  type PP (Ands p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Ands"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let msg1 = msg0 ++ "(" ++ show (length p) ++ ")"
+            w = case findIndex not (toList p) of
+                  Nothing -> ""
+                  Just i -> " i="++show i
+        in mkNodeB opts (and p) (msg1 <> w <> showVerbose opts " | " p) [hh pp]
+
+-- | similar to 'Data.Foldable.or'
+--
+-- >>> pz @(Ors Id) [False,False,False]
+-- FalseT
+--
+-- >>> pl @(Ors Id) [True,True,True,False]
+-- True (Ors(4) i=0 | [True,True,True,False])
+-- TrueT
+--
+-- >>> pl @(Ors Id) []
+-- False (Ors(0) | [])
+-- FalseT
+--
+data Ors p
+
+instance (PP p x ~ t a
+        , P p x
+        , Show (t a)
+        , Foldable t
+        , a ~ Bool
+        ) => P (Ors p) x where
+  type PP (Ors p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Ors"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let msg1 = msg0 ++ "(" ++ show (length p) ++ ")"
+            w = case findIndex id (toList p) of
+                  Nothing -> ""
+                  Just i -> " i="++show i
+        in mkNodeB opts (or p) (msg1 <> w <> showVerbose opts " | " p) [hh pp]
+
+ src/Predicate/Data/ReadShow.hs view
@@ -0,0 +1,412 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted read, show, and printf functions
+-}
+module Predicate.Data.ReadShow (
+
+    ShowP
+  , ReadP
+  , ReadP'
+  , ReadMaybe
+  , ReadMaybe'
+
+  -- ** print expressions
+  , PrintF
+  , PrintC
+  , PrintL
+  , PrintT
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import GHC.TypeLits (Nat,KnownNat)
+import qualified GHC.TypeLits as GL
+import Data.Proxy
+import Data.Kind (Type)
+import Text.Printf
+import qualified Control.Exception as E
+import Data.Typeable
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+-- >>> import Data.Time
+
+-- | similar to 'show'
+--
+-- >>> pz @(ShowP Id) [4,8,3,9]
+-- PresentT "[4,8,3,9]"
+--
+-- >>> pz @(ShowP Id) 'x'
+-- PresentT "'x'"
+--
+-- >>> pz @(ShowP (42 -% 10)) 'x'
+-- PresentT "(-21) % 5"
+--
+data ShowP p
+
+instance ( Show (PP p x)
+         , P p x
+         ) => P (ShowP p) x where
+  type PP (ShowP p) x = String
+  eval _ opts x = do
+    let msg0 = "ShowP"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = show p
+        in mkNode opts (PresentT d) (msg0 <> " " <> litL opts d <> showVerbose opts " | " p) [hh pp]
+
+-- | uses the 'Read' of the given type \'t\' and \'p\' which points to the content to read
+data ReadP' t p
+
+instance (P p x
+        , PP p x ~ String
+        , Typeable (PP t x)
+        , Show (PP t x)
+        , Read (PP t x)
+        ) => P (ReadP' t p) x where
+  type PP (ReadP' t p) x = PP t x
+  eval _ opts x = do
+    let msg0 = "ReadP " <> t
+        t = showT @(PP t x)
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right s ->
+        let hhs = [hh pp]
+        in case reads @(PP t x) s of
+           [(b,"")] -> mkNode opts (PresentT b) (msg0 <> " " ++ showL opts b) hhs
+           o -> mkNode opts (FailT (msg0 <> " (" ++ s ++ ")")) (showVerbose opts "" o) hhs
+
+-- | uses the 'Read' of the given type \'t\' and \'p\' which points to the content to read
+--
+-- >>> pz @(ReadP Rational Id) "4 % 5"
+-- PresentT (4 % 5)
+--
+-- >>> pz @(Between (ReadP Day "2017-04-11") (ReadP Day "2018-12-30") (ReadP Day Id)) "2018-10-12"
+-- TrueT
+--
+-- >>> pz @(Between (ReadP Day "2017-04-11") (ReadP Day "2018-12-30") (ReadP Day Id)) "2016-10-12"
+-- FalseT
+--
+-- >>> pl @(ReadP Rational Id) "123 % 4"
+-- Present 123 % 4 (ReadP Ratio Integer 123 % 4)
+-- PresentT (123 % 4)
+--
+-- >>> pl @(ReadP Rational Id) "x123 % 4"
+-- Error ReadP Ratio Integer (x123 % 4) ([])
+-- FailT "ReadP Ratio Integer (x123 % 4)"
+--
+-- >>> pl @(ReadP Day Id) "1999-11-30"
+-- Present 1999-11-30 (ReadP Day 1999-11-30)
+-- PresentT 1999-11-30
+--
+-- >>> pl @(ReadP Day Id) "1999-02-29"
+-- Error ReadP Day (1999-02-29) ([])
+-- FailT "ReadP Day (1999-02-29)"
+--
+-- >>> pl @(ReadP TimeOfDay Id) "14:59:20"
+-- Present 14:59:20 (ReadP TimeOfDay 14:59:20)
+-- PresentT 14:59:20
+--
+data ReadP (t :: Type) p
+type ReadPT (t :: Type) p = ReadP' (Hole t) p
+
+instance P (ReadPT t p) x => P (ReadP t p) x where
+  type PP (ReadP t p) x = PP (ReadPT t p) x
+  eval _ = eval (Proxy @(ReadPT t p))
+
+
+-- [] (a,s) (a,[])
+
+-- | Read but returns the Maybe of the value and any remaining unparsed string
+--
+-- >>> pz @(ReadMaybe Int Id) "123x"
+-- PresentT (Just (123,"x"))
+--
+-- >>> pz @(ReadMaybe Int Id) "123"
+-- PresentT (Just (123,""))
+--
+-- >>> pz @(ReadMaybe Int Id) "x123"
+-- PresentT Nothing
+--
+data ReadMaybe' t p
+
+instance (P p x
+        , PP p x ~ String
+        , Typeable (PP t x)
+        , Show (PP t x)
+        , Read (PP t x)
+        ) => P (ReadMaybe' t p) x where
+  type PP (ReadMaybe' t p) x = Maybe (PP t x, String)
+  eval _ opts x = do
+    let msg0 = "ReadMaybe " <> t
+        t = showT @(PP t x)
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right s ->
+        let msg1 = msg0 <> " (" <> s <> ")"
+            hhs = [hh pp]
+        in case reads @(PP t x) s of
+           [(b,rest)] -> mkNode opts (PresentT (Just (b,rest))) (lit01 opts msg1 b "" s) hhs
+           o -> mkNode opts (PresentT Nothing) (msg1 <> " failed" <> showVerbose opts " " o) hhs
+
+data ReadMaybe (t :: Type) p
+type ReadMaybeT (t :: Type) p = ReadMaybe' (Hole t) p
+
+instance P (ReadMaybeT t p) x => P (ReadMaybe t p) x where
+  type PP (ReadMaybe t p) x = PP (ReadMaybeT t p) x
+  eval _ = eval (Proxy @(ReadMaybeT t p))
+
+-- | uses PrintF (unsafe) to format output for a single value
+--
+-- >>> pz @(PrintF "value=%03d" Id) 12
+-- PresentT "value=012"
+--
+-- >>> pz @(PrintF "%s" (Fst Id)) ("abc",'x')
+-- PresentT "abc"
+--
+-- >>> pz @(PrintF "%d" (Fst Id)) ("abc",'x')
+-- FailT "PrintF (IO e=printf: bad formatting char 'd')"
+--
+-- >>> pl @(PrintF "someval %d" Id) ("!23"::String)
+-- Error PrintF (IO e=printf: bad formatting char 'd') ("!23" s=someval %d)
+-- FailT "PrintF (IO e=printf: bad formatting char 'd')"
+--
+-- >>> pl @(PrintF "%-6s" Id) (1234 :: Int)
+-- Error PrintF (IO e=printf: bad formatting char 's') (1234 s=%-6s)
+-- FailT "PrintF (IO e=printf: bad formatting char 's')"
+--
+-- >>> pl @(PrintF "%06x" Id) (1234 :: Int)
+-- Present "0004d2" (PrintF [0004d2] | p=1234 | s=%06x)
+-- PresentT "0004d2"
+--
+-- >>> pl @(Msg (PrintF "digits=%d" Len) (Head Id)) [1..4]
+-- Present 1 (digits=4 Head 1 | [1,2,3,4])
+-- PresentT 1
+--
+-- >>> pl @(PrintF "ask%%dfas%%kef%05d hey %%" Id) (35 :: Int)
+-- Present "ask%dfas%kef00035 hey %" (PrintF [ask%dfas%kef00035 hey %] | p=35 | s=ask%%dfas%%kef%05d hey %%)
+-- PresentT "ask%dfas%kef00035 hey %"
+--
+-- >>> pl @(Fail () (PrintF "someval int=%d" Id)) (45 :: Int)
+-- Error someval int=45 (Fail someval int=45)
+-- FailT "someval int=45"
+--
+data PrintF s p
+
+instance (PrintfArg (PP p x)
+        , Show (PP p x)
+        , PP s x ~ String
+        , P s x
+        , P p x
+        ) => P (PrintF s p) x where
+  type PP (PrintF s p) x = String
+  eval _ opts x = do
+    let msg0 = "PrintF"
+    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
+    case lrx of
+      Left e -> pure e
+      Right (s,p,ss,pp) -> do
+        lr <- catchitNF @_ @E.SomeException (printf s p)
+        pure $ case lr of
+          Left e -> mkNode opts (FailT (msg0 <> " (" <> e <> ")")) (showL opts p <> " s=" <> s) [hh ss, hh pp]
+          Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> litL opts ret <> "]" <> showVerbose opts " | p=" p <> litVerbose opts " | s=" s) [hh ss, hh pp]
+
+
+-- | uses inductive tuples to replace variable arguments
+--
+class PrintC x where
+  prtC :: (PrintfArg a, PrintfType r) => String -> (a,x) -> r
+instance PrintC () where
+  prtC s (a,()) = printf s a
+instance ( PrintfArg a
+         , PrintC rs
+         ) => PrintC (a,rs) where
+  prtC s (a,rs) = prtC s rs a
+
+-- | print for flat n-tuples of size two or larger
+--
+-- >>> pl @(PrintT "%d %s %s %s" '(Fst Id, Snd Id, Snd Id,Snd Id)) (10,"Asdf")
+-- Present "10 Asdf Asdf Asdf" (PrintT [10 Asdf Asdf Asdf] | s=%d %s %s %s)
+-- PresentT "10 Asdf Asdf Asdf"
+--
+-- >>> pl @(PrintT "%c %d %s" Id) ('x', 10,"Asdf")
+-- Present "x 10 Asdf" (PrintT [x 10 Asdf] | s=%c %d %s)
+-- PresentT "x 10 Asdf"
+--
+-- >>> pz @(PrintT "fst=%s snd=%03d" Id) ("ab",123)
+-- PresentT "fst=ab snd=123"
+--
+-- >>> pz @(PrintT "fst=%s snd=%03d thd=%s" Id) ("ab",123,"xx")
+-- PresentT "fst=ab snd=123 thd=xx"
+--
+-- >>> pl @(PrintT "%s %d %c %s" '(W "xyz", Fst Id, Snd Id, Thd Id)) (123,'x',"ab")
+-- Present "xyz 123 x ab" (PrintT [xyz 123 x ab] | s=%s %d %c %s)
+-- PresentT "xyz 123 x ab"
+--
+-- >>> pl @(PrintT "%d %c %s" Id) (123,'x')
+-- Error PrintT(IO e=printf: argument list ended prematurely) (PrintT %d %c %s)
+-- FailT "PrintT(IO e=printf: argument list ended prematurely)"
+--
+-- >>> pl @(PrintT "%d %c %s" Id) (123,'x',"abc",11)
+-- Error PrintT(IO e=printf: formatting string ended prematurely) (PrintT %d %c %s)
+-- FailT "PrintT(IO e=printf: formatting string ended prematurely)"
+--
+-- >>> pl @(PrintT "lhs = %d rhs = %s" Id) (123::Int,"asdf"::String)
+-- Present "lhs = 123 rhs = asdf" (PrintT [lhs = 123 rhs = asdf] | s=lhs = %d rhs = %s)
+-- PresentT "lhs = 123 rhs = asdf"
+--
+-- >>> pl @(PrintT "d=%03d s=%s" Id) (9::Int,"ab"::String)
+-- Present "d=009 s=ab" (PrintT [d=009 s=ab] | s=d=%03d s=%s)
+-- PresentT "d=009 s=ab"
+--
+-- >>> pl @(PrintT "d=%03d s=%s c=%c f=%4.2f" Id) (9::Int,"ab"::String,'x',1.54::Float)
+-- Present "d=009 s=ab c=x f=1.54" (PrintT [d=009 s=ab c=x f=1.54] | s=d=%03d s=%s c=%c f=%4.2f)
+-- PresentT "d=009 s=ab c=x f=1.54"
+--
+-- >>> pl @(PrintT "d=%03d s=%s" Id) (9::Int, "ab"::String,'x',1.54::Float)
+-- Error PrintT(IO e=printf: formatting string ended prematurely) (PrintT d=%03d s=%s)
+-- FailT "PrintT(IO e=printf: formatting string ended prematurely)"
+--
+-- >>> pl @(PrintT "lhs = %d rhs = %s c=%d" Id) (123::Int,"asdf"::String,'x')
+-- Present "lhs = 123 rhs = asdf c=120" (PrintT [lhs = 123 rhs = asdf c=120] | s=lhs = %d rhs = %s c=%d)
+-- PresentT "lhs = 123 rhs = asdf c=120"
+--
+-- >>> pl @(PrintT "hello d=%d %c %s" '(12, Char1 "z", "someval")) ()
+-- Present "hello d=12 z someval" (PrintT [hello d=12 z someval] | s=hello d=%d %c %s)
+-- PresentT "hello d=12 z someval"
+--
+-- >>> pl @(PrintT "ipaddress %03d.%03d.%03d.%03d" '(1,2,3,4)) ()
+-- Present "ipaddress 001.002.003.004" (PrintT [ipaddress 001.002.003.004] | s=ipaddress %03d.%03d.%03d.%03d)
+-- PresentT "ipaddress 001.002.003.004"
+--
+data PrintT s p
+instance (PrintC bs
+        , (b,bs) ~ InductTupleP y
+        , InductTupleC y
+        , PrintfArg b
+        , PP s x ~ String
+        , PP p x ~ y
+        , P s x
+        , P p x
+        , CheckT (PP p x) ~ 'True
+        ) => P (PrintT s p) x where
+  type PP (PrintT s p) x = String
+  eval _ opts x = do
+    let msg0 = "PrintT"
+    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
+    case lrx of
+      Left e -> pure e
+      Right (s,y,ss,pp) -> do
+        let hhs = [hh ss, hh pp]
+        lr <- catchitNF @_ @E.SomeException (prtC @bs s (inductTupleC y))
+        pure $ case lr of
+          Left e -> mkNode opts (FailT (msg0 <> "(" <> e <> ")")) (msg0 <> " " <> s) hhs
+          Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> litL opts ret <> "] | s=" <> litL opts s) hhs
+
+type family CheckT (tp :: Type) :: Bool where
+  CheckT () = GL.TypeError ('GL.Text "Printfn: inductive tuple cannot be empty")
+  CheckT o = 'True
+
+
+-- | print for lists  -- use 'PrintT' as it is safer than 'PrintL'
+--
+-- >>> pl @(PrintL 4 "%s %s %s %s" '[W "xyz", ShowP (Fst Id), ShowP (Snd Id), Thd Id]) (123,'x',"ab")
+-- Present "xyz 123 'x' ab" (PrintL(4) [xyz 123 'x' ab] | s=%s %s %s %s)
+-- PresentT "xyz 123 'x' ab"
+--
+-- >>> pz @(PrintL 1 "%05d" '[Id]) 123  -- tick is required for a one element list (use 'PrintF')
+-- PresentT "00123"
+--
+-- >>> pz @(PrintL 2 "%d %05d" [Fst Id,Snd Id]) (29,123)
+-- PresentT "29 00123"
+--
+-- >>> pl @(PrintL 3 "first=%d second=%d third=%d" Id) [10,11,12]
+-- Present "first=10 second=11 third=12" (PrintL(3) [first=10 second=11 third=12] | s=first=%d second=%d third=%d)
+-- PresentT "first=10 second=11 third=12"
+--
+-- >>> pl @(PrintL 2 "first=%d second=%d third=%d" Id) [10,11,12]
+-- Error PrintL(2) arg count=3 (wrong length 3)
+-- FailT "PrintL(2) arg count=3"
+--
+-- >>> pl @(PrintL 4 "first=%d second=%d third=%d" Id) [10,11,12]
+-- Error PrintL(4) arg count=3 (wrong length 3)
+-- FailT "PrintL(4) arg count=3"
+--
+-- >>> pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4::Int]
+-- Present "001.002.003.004" (PrintL(4) [001.002.003.004] | s=%03d.%03d.%03d.%03d)
+-- PresentT "001.002.003.004"
+--
+-- >>> pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4,5::Int]
+-- Error PrintL(4) arg count=5 (wrong length 5)
+-- FailT "PrintL(4) arg count=5"
+--
+-- >>> pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3::Int]
+-- Error PrintL(4) arg count=3 (wrong length 3)
+-- FailT "PrintL(4) arg count=3"
+--
+-- >>> pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4::Int]
+-- Present "001.002.003.004" (PrintL(4) [001.002.003.004] | s=%03d.%03d.%03d.%03d)
+-- PresentT "001.002.003.004"
+--
+-- >>> pl @(PrintL 4 "%d %4d %-d %03d" Id) [1..4::Int]
+-- Present "1    2 3 004" (PrintL(4) [1    2 3 004] | s=%d %4d %-d %03d)
+-- PresentT "1    2 3 004"
+--
+
+data PrintL (n :: Nat) s p
+
+instance (KnownNat n
+        , PrintC bs
+        , (b,bs) ~ InductListP n a
+        , InductListC n a
+        , PrintfArg b
+        , PP s x ~ String
+        , PP p x ~ [a]
+        , P s x
+        , P p x
+        ) => P (PrintL n s p) x where
+  type PP (PrintL n s p) x = String
+  eval _ opts x = do
+    let msg0 = "PrintL(" ++ show n ++ ")"
+        n = nat @n
+    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
+    case lrx of
+      Left e -> pure e
+      Right (s,p,ss,pp) -> do
+        let hhs = [hh ss, hh pp]
+        if length p /= n then pure $ mkNode opts (FailT (msg0 <> " arg count=" ++ show (length p))) ("wrong length " ++ show (length p)) hhs
+        else do
+          lr <- catchitNF @_ @E.SomeException (prtC @bs s (inductListC @n @a p))
+          pure $ case lr of
+            Left e -> mkNode opts (FailT (msg0 <> "(" <> e <> ")")) ("s=" <> s) hhs
+            Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> litL opts ret <> "] | s=" <> litL opts s) hhs
+
+ src/Predicate/Data/Regex.hs view
@@ -0,0 +1,602 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted regular expression functions
+-}
+module Predicate.Data.Regex (
+
+  -- ** regex expressions
+    Re
+  , Re'
+  , Rescan
+  , Rescan'
+  , RescanRanges
+  , RescanRanges'
+  , Resplit
+  , Resplit'
+  , ReplaceAll
+  , ReplaceAll'
+  , ReplaceOne
+  , ReplaceOne'
+  , ReplaceAllString
+  , ReplaceAllString'
+  , ReplaceOneString
+  , ReplaceOneString'
+  , ReplaceFn
+  , ReplaceFn1
+  , ReplaceFn2
+  , ReplaceFn3
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Data.Proxy
+import qualified Text.Regex.PCRE.Heavy as RH
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Safe (readNote)
+-- >>> import Predicate.Prelude
+-- >>> import Data.Time
+
+-- | runs a regular expression with given regex options and returns a boolean: see 'RH.=~'
+--
+-- >>> pl @(Re' '[ 'Caseless, 'Dotall ] "ab" Id) "aB"
+-- True (Re' ['Caseless, 'Dotall] (ab) | aB)
+-- TrueT
+--
+-- >>> pl @(Re' '[ 'Caseless, 'Dotall ] "ab." Id) "aB\n"
+-- True (Re' ['Caseless, 'Dotall] (ab.) | aB
+-- )
+-- TrueT
+--
+-- >>> pl @(Re' '[ 'Caseless ] "ab." Id) "aB\n"
+-- False (Re' ['Caseless] (ab.) | aB
+-- )
+-- FalseT
+--
+data Re' (rs :: [ROpt]) p q
+
+-- | runs a regular expression and returns a boolean: see 'RH.=~'
+--
+-- >>> pz @(Re "^\\d{2}:\\d{2}:\\d{2}$" Id) "13:05:25"
+-- TrueT
+--
+-- >>> pl @(Re "\\d{4}-\\d{3}" Id) "1234-123"
+-- True (Re (\d{4}-\d{3}) | 1234-123)
+-- TrueT
+--
+-- >>> pl @(Re "\\d{4}-\\d{3}" Id) "1234-1x3"
+-- False (Re (\d{4}-\d{3}) | 1234-1x3)
+-- FalseT
+--
+-- >>> pl @(Re "(?i)ab" Id) "aB" -- runtime [use 'Caseless instead]
+-- True (Re ((?i)ab) | aB)
+-- TrueT
+--
+-- >>> pl @(Re "ab" Id) "aB"
+-- False (Re (ab) | aB)
+-- FalseT
+--
+-- >>> pl @(Re "^\\d{1,3}(?:\\.\\d{1,3}){3}$" Id) "123.1.1.21"
+-- True (Re (^\d{1,3}(?:\.\d{1,3}){3}$) | 123.1.1.21)
+-- TrueT
+--
+-- >>> pl @(Guard "regex failed" (Re "^\\d+(?:\\.\\d+)?$" Id) >> ReadP Double Id) "13.345"
+-- Present 13.345 ((>>) 13.345 | {ReadP Double 13.345})
+-- PresentT 13.345
+--
+-- >>> pl @(Guard "regex failed" (Re "^\\d+(?:\\.\\d+)?$" Id) >> ReadP Double Id) "13"
+-- Present 13.0 ((>>) 13.0 | {ReadP Double 13.0})
+-- PresentT 13.0
+--
+-- >>> pl @(ExitWhen "regex failed" (Not (Re "^\\d+(?:\\.\\d+)?$" Id)) >> ReadP Double Id) "-13.4"
+-- Error regex failed ((>>) lhs failed)
+-- FailT "regex failed"
+--
+-- >>> pl @(Re "\\d{4}\\" Id) "ayx"
+-- Error Regex failed to compile (Re (\d{4}\) ([],[]):\ at end of pattern)
+-- FailT "Regex failed to compile"
+--
+-- >>> pl @(Re "^\\d+$" Id) "123\nx"
+-- False (Re (^\d+$) | 123
+-- x)
+-- FalseT
+--
+-- >>> pl @(Re "(?m)^\\d+$" Id) "123\nx" -- (?m) anchors match beginning/end of line instead of whole string
+-- True (Re ((?m)^\d+$) | 123
+-- x)
+-- TrueT
+--
+-- >>> pl @(Catch (Re "\\d+(" Id) 'False) "123"
+-- False (Catch caught exception[Regex failed to compile])
+-- FalseT
+--
+-- >>> pl @(Catch (Re "\\d+" Id) 'False) "123"
+-- True (Catch did not fire)
+-- TrueT
+--
+data Re p q
+
+instance (GetROpts rs
+        , PP p x ~ String
+        , PP q x ~ String
+        , P p x
+        , P q x
+        ) => P (Re' rs p q) x where
+  type PP (Re' rs p q) x = Bool
+  eval _ opts x = do
+    let msg0 = "Re" <> unlessNull rs ("' " <> displayROpts fs)
+        (fs,rs) = getROpts @rs
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case compileRegex @rs opts msg1 p hhs of
+            Left tta -> tta
+            Right regex ->
+               let b = q RH.=~ regex
+               in mkNodeB opts b (msg1 <> litVerbose opts " | " q) hhs
+
+type ReT p q = Re' '[] p q
+
+instance P (ReT p q) x => P (Re p q) x where
+  type PP (Re p q) x = PP (ReT p q) x
+  eval _ = evalBool (Proxy @(ReT p q))
+
+-- only way with rescan is to be explicit: no repeats! and useanchors but not (?m)
+-- or just use Re' but then we only get a bool ie doesnt capture groups
+-- rescan returns Right [] as an failure!
+-- [] is failure!
+--  anchored means it has to start at the beginning: can have junk on the end which we cant detect but at least we know it starts at beginning
+
+
+-- | runs a regex matcher returning the original values and optionally any groups: see 'RH.scan'
+--
+-- >>> pl @(Rescan' '[ 'Anchored ] "([[:xdigit:]]{2})" Id) "wfeb12az"
+-- Error Regex no results (Rescan' ['Anchored] (([[:xdigit:]]{2})) | "wfeb12az")
+-- FailT "Regex no results"
+--
+data Rescan' (rs :: [ROpt]) p q
+
+instance (GetROpts rs
+        , PP p x ~ String
+        , PP q x ~ String
+        , P p x
+        , P q x
+        ) => P (Rescan' rs p q) x where
+  type PP (Rescan' rs p q) x = [(String, [String])]
+  eval _ opts x = do
+    let msg0 = "Rescan" <> unlessNull rs ("' " <> displayROpts fs)
+        (fs,rs) = getROpts @rs
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case compileRegex @rs opts msg1 p hhs of
+          Left tta -> tta
+          Right regex ->
+            case splitAt (oRecursion opts) $ RH.scan regex q of
+              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
+              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
+                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) [hh pp, hh qq]
+              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) [hh pp, hh qq]
+
+-- | see 'RH.scan'
+--
+-- >>> pz @(Rescan "^(\\d{2}):(\\d{2}):(\\d{2})$" Id) "13:05:25"
+-- PresentT [("13:05:25",["13","05","25"])]
+--
+-- >>> pz @(Rescan (Snd Id) "13:05:25") ('a',"^(\\d{2}):(\\d{2}):(\\d{2})$")
+-- PresentT [("13:05:25",["13","05","25"])]
+--
+-- >>> pz @(Rescan "^(\\d{2}):(\\d{2}):(\\d{2})$" Id >> Snd (Head Id) >> Map (ReadP Int Id) Id) "13:05:25"
+-- PresentT [13,5,25]
+--
+-- >>> pl @(Rescan "(\\d+)\\D?" Id >> Map (Second (ReadP Int (OneP Id))) Id) "123-444-987"
+-- Present [("123-",123),("444-",444),("987",987)] ((>>) [("123-",123),("444-",444),("987",987)] | {Map [("123-",123),("444-",444),("987",987)] | [("123-",["123"]),("444-",["444"]),("987",["987"])]})
+-- PresentT [("123-",123),("444-",444),("987",987)]
+--
+-- >>> pl @(Rescan ".(.)" Id) "aBcd"
+-- Present [("aB",["B"]),("cd",["d"])] (Rescan (.(.)) [("aB",["B"]),("cd",["d"])] | aBcd)
+-- PresentT [("aB",["B"]),("cd",["d"])]
+--
+-- >>> pl @(Rescan "\\d{1,3}(\\.)?" Id) "123.8.99.21"
+-- Present [("123.",["."]),("8.",["."]),("99.",["."]),("21",[])] (Rescan (\d{1,3}(\.)?) [("123.",["."]),("8.",["."]),("99.",["."]),("21",[])] | 123.8.99.21)
+-- PresentT [("123.",["."]),("8.",["."]),("99.",["."]),("21",[])]
+--
+-- >>> pl @(Map (Fst Id) (Rescan "." (ShowP Id)) >> Filter (Same "2") Id) 12324
+-- Present ["2","2"] ((>>) ["2","2"] | {Fst ["2","2"] | (["2","2"],["1","3","4"])})
+-- PresentT ["2","2"]
+--
+-- >>> pl @(Rescan "(\\d)+?" Id) "1234"
+-- Present [("1",["1"]),("2",["2"]),("3",["3"]),("4",["4"])] (Rescan ((\d)+?) [("1",["1"]),("2",["2"]),("3",["3"]),("4",["4"])] | 1234)
+-- PresentT [("1",["1"]),("2",["2"]),("3",["3"]),("4",["4"])]
+--
+-- >>> pl @(Rescan "(\\d)+" Id) "1234"
+-- Present [("1234",["4"])] (Rescan ((\d)+) [("1234",["4"])] | 1234)
+-- PresentT [("1234",["4"])]
+--
+-- >>> pl @(Rescan "(\\d{1,3})(\\.(\\d{1,3}))+?" Id) "1.2.3.4" -- overcapturing
+-- Present [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])] (Rescan ((\d{1,3})(\.(\d{1,3}))+?) [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])] | 1.2.3.4)
+-- PresentT [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])]
+--
+-- >>> pl @(Rescan "^(\\d)+?$" Id) "1234"
+-- Present [("1234",["4"])] (Rescan (^(\d)+?$) [("1234",["4"])] | 1234)
+-- PresentT [("1234",["4"])]
+--
+-- >>> pl @(Rescan "(\\d{1,3})(\\.(\\d{1,3}))+?" Id) "1.2.3.4"
+-- Present [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])] (Rescan ((\d{1,3})(\.(\d{1,3}))+?) [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])] | 1.2.3.4)
+-- PresentT [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])]
+--
+-- >>> pl @(Rescan "(\\d{1,3})(?:\\.(\\d{1,3}))+?" Id) "1.2.3.4" -- bizzare!
+-- Present [("1.2",["1","2"]),("3.4",["3","4"])] (Rescan ((\d{1,3})(?:\.(\d{1,3}))+?) [("1.2",["1","2"]),("3.4",["3","4"])] | 1.2.3.4)
+-- PresentT [("1.2",["1","2"]),("3.4",["3","4"])]
+--
+-- >>> pl @(Rescan "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" Id) "1.2.3.4"
+-- Present [("1.2.3.4",["1","2","3","4"])] (Rescan (^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$) [("1.2.3.4",["1","2","3","4"])] | 1.2.3.4)
+-- PresentT [("1.2.3.4",["1","2","3","4"])]
+--
+-- >>> pl @(Rescan "([[:xdigit:]]{2})" Id) "wfeb12az"
+-- Present [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])] (Rescan (([[:xdigit:]]{2})) [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])] | wfeb12az)
+-- PresentT [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])]
+--
+data Rescan p q
+type RescanT p q = Rescan' '[] p q
+
+instance P (RescanT p q) x => P (Rescan p q) x where
+  type PP (Rescan p q) x = PP (RescanT p q) x
+  eval _ = eval (Proxy @(RescanT p q))
+
+
+-- | see 'RH.scanRanges'
+--
+-- >>> pz @(RescanRanges "^(\\d{2}):(\\d{2}):(\\d{2})$" Id) "13:05:25"
+-- PresentT [((0,8),[(0,2),(3,5),(6,8)])]
+--
+data RescanRanges' (rs :: [ROpt]) p q
+
+instance (GetROpts rs
+        , PP p x ~ String
+        , PP q x ~ String
+        , P p x
+        , P q x
+        ) => P (RescanRanges' rs p q) x where
+  type PP (RescanRanges' rs p q) x = [((Int,Int), [(Int,Int)])]
+  eval _ opts x = do
+    let msg0 = "RescanRanges" <> unlessNull rs ("' " <> displayROpts fs)
+        (fs,rs) = getROpts @rs
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case compileRegex @rs opts msg1 p hhs of
+          Left tta -> tta
+          Right regex ->
+            case splitAt (oRecursion opts) $ RH.scanRanges regex q of
+              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
+              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
+                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) hhs
+              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) hhs
+
+data RescanRanges p q
+type RescanRangesT p q = RescanRanges' '[] p q
+
+instance P (RescanRangesT p q) x => P (RescanRanges p q) x where
+  type PP (RescanRanges p q) x = PP (RescanRangesT p q) x
+  eval _ = eval (Proxy @(RescanRangesT p q))
+
+-- | splits a string on a regex delimiter: see 'RH.split'
+--
+-- >>> pl @(Resplit' '[ 'Caseless ] "aBc" Id) "123AbC456abc"
+-- Present ["123","456",""] (Resplit' ['Caseless] (aBc) ["123","456",""] | 123AbC456abc)
+-- PresentT ["123","456",""]
+--
+data Resplit' (rs :: [ROpt]) p q
+
+instance (GetROpts rs
+        , PP p x ~ String
+        , PP q x ~ String
+        , P p x
+        , P q x
+        ) => P (Resplit' rs p q) x where
+  type PP (Resplit' rs p q) x = [String]
+  eval _ opts x = do
+    let msg0 = "Resplit" <> unlessNull rs ("' " <> displayROpts fs)
+        (fs,rs) = getROpts @rs
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case compileRegex @rs opts msg1 p hhs of
+          Left tta -> tta
+          Right regex ->
+            case splitAt (oRecursion opts) $ RH.split regex q of
+              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
+              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
+                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) hhs
+              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) hhs
+
+-- | splits a string on a regex delimiter: see 'RH.split'
+--
+-- >>> pz @(Resplit "\\." Id) "141.201.1.22"
+-- PresentT ["141","201","1","22"]
+--
+-- >>> pz @(Resplit (Singleton (Fst Id)) (Snd Id)) (':', "12:13:1")
+-- PresentT ["12","13","1"]
+--
+-- >>> pl @(Resplit "\\." Id) "123.2.3.5.6"
+-- Present ["123","2","3","5","6"] (Resplit (\.) ["123","2","3","5","6"] | 123.2.3.5.6)
+-- PresentT ["123","2","3","5","6"]
+--
+-- >>> pl @(Map (ReadP Int Id) (Resplit "\\." Id) >> '(Id, '(Len == 4, All (Between 0 255 Id) Id))) "141.214.125.1.2.3333"
+-- Present ([141,214,125,1,2,3333],(False,False)) ((>>) ([141,214,125,1,2,3333],(False,False)) | {'([141,214,125,1,2,3333],(False,False))})
+-- PresentT ([141,214,125,1,2,3333],(False,False))
+--
+-- >>> pl @(Map (ReadP Int Id) (Resplit "\\." Id) >> Id &&& ((Len == 4) &&& All (Between 0 255 Id) Id)) "141.214.125.1.2.6"
+-- Present ([141,214,125,1,2,6],(False,True)) ((>>) ([141,214,125,1,2,6],(False,True)) | {W '([141,214,125,1,2,6],(False,True))})
+-- PresentT ([141,214,125,1,2,6],(False,True))
+--
+-- >>> pl @(Resplit "\\." Id >> Map (ReadP Int Id) Id >> Id &&& ((Len == 4) &&& All (Between 0 255 Id) Id)) "141.214.125."
+-- Error ReadP Int () (["141","214","125",""] (>>) rhs failed)
+-- FailT "ReadP Int ()"
+--
+data Resplit p q
+type ResplitT p q = Resplit' '[] p q
+
+instance P (ResplitT p q) x => P (Resplit p q) x where
+  type PP (Resplit p q) x = PP (ResplitT p q) x
+  eval _ = eval (Proxy @(ResplitT p q))
+
+-- | replaces regex \'s\' with a string \'s1\' inside the value: see 'RH.sub' and 'RH.gsub'
+--
+-- >>> pz @(ReplaceAllString 'ROverWrite "\\." ":" Id) "141.201.1.22"
+-- PresentT "141:201:1:22"
+--
+data ReplaceImpl (alle :: Bool) (rs :: [ROpt]) p q r
+
+instance (GetBool b
+        , GetROpts rs
+        , PP p x ~ String
+        , PP q x ~ RReplace
+        , PP r x ~ String
+        , P p x
+        , P q x
+        , P r x
+        ) => P (ReplaceImpl b rs p q r) x where
+  type PP (ReplaceImpl b rs p q r) x = String
+  eval _ opts x = do
+    let msg0 = "Replace" <> (if alle then "All" else "One") <> unlessNull rs ("' " <> displayROpts fs)
+        (fs,rs) = getROpts @rs
+        alle = getBool @b
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    case lr of
+      Left e -> pure e
+      Right (p,q,pp,qq) ->
+        let msg1 = msg0 <> " (" <> p <> ")"
+            hhs = [hh pp, hh qq]
+        in case compileRegex @rs opts msg1 p hhs of
+          Left tta -> pure tta
+          Right regex -> do
+            rr <- eval (Proxy @r) opts x
+            pure $ case getValueLR opts msg0 rr hhs of
+              Left e -> e
+              Right r ->
+               let ret :: String
+                   ret = case q of
+                           RReplace o s ->
+                             let g fn = (if alle then RH.gsub else RH.sub) regex fn r
+                             in g (case o of
+                                  RPrepend -> (s <>)
+                                  ROverWrite -> const s
+                                  RAppend -> (<> s))
+                           RReplace1 s -> (if alle then RH.gsub else RH.sub) regex s r
+                           RReplace2 s -> (if alle then RH.gsub else RH.sub) regex s r
+                           RReplace3 s -> (if alle then RH.gsub else RH.sub) regex s r
+               in mkNode opts (PresentT ret) (msg1 <> " " <> litL opts r <> litVerbose opts " | " ret) (hhs <> [hh rr])
+
+data ReplaceAll' (rs :: [ROpt]) p q r
+type ReplaceAllT' (rs :: [ROpt]) p q r = ReplaceImpl 'True rs p q r
+
+instance P (ReplaceAllT' rs p q r) x => P (ReplaceAll' rs p q r) x where
+  type PP (ReplaceAll' rs p q r) x = PP (ReplaceAllT' rs p q r) x
+  eval _ = eval (Proxy @(ReplaceAllT' rs p q r))
+
+data ReplaceAll p q r
+type ReplaceAllT p q r = ReplaceAll' '[] p q r
+
+instance P (ReplaceAllT p q r) x => P (ReplaceAll p q r) x where
+  type PP (ReplaceAll p q r) x = PP (ReplaceAllT p q r) x
+  eval _ = eval (Proxy @(ReplaceAllT p q r))
+
+data ReplaceOne' (rs :: [ROpt]) p q r
+type ReplaceOneT' (rs :: [ROpt]) p q r = ReplaceImpl 'False rs p q r
+
+instance P (ReplaceOneT' rs p q r) x => P (ReplaceOne' rs p q r) x where
+  type PP (ReplaceOne' rs p q r) x = PP (ReplaceOneT' rs p q r) x
+  eval _ = eval (Proxy @(ReplaceOneT' rs p q r))
+
+-- | replace first occurrence of string \'p\' with \'q\' in \'r\'
+--
+-- >>> pl @(ReplaceOneString 'ROverWrite "abc" "def" Id) "123abc456abc"
+-- Present "123def456abc" (ReplaceOne (abc) 123abc456abc | 123def456abc)
+-- PresentT "123def456abc"
+--
+-- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1530144000123+0530)"
+-- PresentT 2018-06-28 05:30:00.123 +0530
+--
+-- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1593460089052+0800)"
+-- PresentT 2020-06-30 03:48:09.052 +0800
+--
+-- >>> pz @(Rescan "^Date\\((\\d+)(\\d{3}[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> (Id !! 0 <> "." <> Id !! 1)  >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1593460089052+0800)"
+-- PresentT 2020-06-30 03:48:09.052 +0800
+--
+data ReplaceOne p q r
+type ReplaceOneT p q r = ReplaceOne' '[] p q r
+
+instance P (ReplaceOneT p q r) x => P (ReplaceOne p q r) x where
+  type PP (ReplaceOne p q r) x = PP (ReplaceOneT p q r) x
+  eval _ = eval (Proxy @(ReplaceOneT p q r))
+
+-- | replace all occurrences of string \'p\' with \'q\' in \'r\'
+--
+-- >>> pl @(ReplaceAllString 'ROverWrite "abc" "def" Id) "123abc456abc"
+-- Present "123def456def" (ReplaceAll (abc) 123abc456abc | 123def456def)
+-- PresentT "123def456def"
+--
+-- >>> pl @(ReplaceAllString' '[] 'ROverWrite "abc" "def" Id) "123AbC456abc"
+-- Present "123AbC456def" (ReplaceAll (abc) 123AbC456abc | 123AbC456def)
+-- PresentT "123AbC456def"
+--
+-- >>> pl @(ReplaceAllString' '[ 'Caseless ] 'ROverWrite "abc" "def" Id) "123AbC456abc"
+-- Present "123def456def" (ReplaceAll' ['Caseless] (abc) 123AbC456abc | 123def456def)
+-- PresentT "123def456def"
+--
+-- >>> pl @(ReplaceAllString 'RPrepend "abc" "def" Id) "123AbC456abc"
+-- Present "123AbC456defabc" (ReplaceAll (abc) 123AbC456abc | 123AbC456defabc)
+-- PresentT "123AbC456defabc"
+--
+-- >>> pl @(ReplaceAllString 'ROverWrite "abc" "def" Id) "123AbC456abc"
+-- Present "123AbC456def" (ReplaceAll (abc) 123AbC456abc | 123AbC456def)
+-- PresentT "123AbC456def"
+--
+-- >>> pl @(ReplaceAllString 'RAppend "abc" "def" Id) "123AbC456abc"
+-- Present "123AbC456abcdef" (ReplaceAll (abc) 123AbC456abc | 123AbC456abcdef)
+-- PresentT "123AbC456abcdef"
+--
+data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
+type ReplaceAllStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceAll' rs p (ReplaceFn o q) r
+
+instance P (ReplaceAllStringT' rs o p q r) x => P (ReplaceAllString' rs o p q r) x where
+  type PP (ReplaceAllString' rs o p q r) x = PP (ReplaceAllStringT' rs o p q r) x
+  eval _ = eval (Proxy @(ReplaceAllStringT' rs o p q r))
+
+data ReplaceAllString o p q r
+type ReplaceAllStringT o p q r = ReplaceAllString' '[] o p q r
+
+instance P (ReplaceAllStringT o p q r) x => P (ReplaceAllString o p q r) x where
+  type PP (ReplaceAllString o p q r) x = PP (ReplaceAllStringT o p q r) x
+  eval _ = eval (Proxy @(ReplaceAllStringT o p q r))
+
+data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
+type ReplaceOneStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceOne' rs p (ReplaceFn o q) r
+
+instance P (ReplaceOneStringT' rs o p q r) x => P (ReplaceOneString' rs o p q r) x where
+  type PP (ReplaceOneString' rs o p q r) x = PP (ReplaceOneStringT' rs o p q r) x
+  eval _ = eval (Proxy @(ReplaceOneStringT' rs o p q r))
+
+data ReplaceOneString (o :: ReplaceFnSub) p q r
+type ReplaceOneStringT (o :: ReplaceFnSub) p q r = ReplaceOneString' '[] o p q r
+
+instance P (ReplaceOneStringT o p q r) x => P (ReplaceOneString o p q r) x where
+  type PP (ReplaceOneString o p q r) x = PP (ReplaceOneStringT o p q r) x
+  eval _ = eval (Proxy @(ReplaceOneStringT o p q r))
+
+-- | Simple replacement string: see 'ReplaceAllString' and 'ReplaceOneString'
+--
+data ReplaceFn (o :: ReplaceFnSub) p
+
+instance (GetReplaceFnSub r
+        , PP p x ~ String
+        , P p x) => P (ReplaceFn r p) x where
+  type PP (ReplaceFn r p) x = RReplace
+  eval _ opts x = do
+    let msg0 = "ReplaceFn"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let b = RReplace (getReplaceFnSub @r) p
+        in mkNode opts (PresentT b) (msg0 <> showVerbose opts " | " p) [hh pp]
+
+-- | A replacement function @(String -> [String] -> String)@ which returns the whole match and the groups
+-- Used by 'RH.sub' and 'RH.gsub'
+--
+-- Requires "Text.Show.Functions"
+--
+data ReplaceFn1 p
+
+instance (PP p x ~ (String -> [String] -> String)
+        , P p x) => P (ReplaceFn1 p) x where
+  type PP (ReplaceFn1 p) x = RReplace
+  eval _ opts x = do
+    let msg0 = "ReplaceFn1 (String -> [String] -> String)"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right f -> mkNode opts (PresentT (RReplace1 f)) msg0 [hh pp]
+
+-- | A replacement function @(String -> String)@ that yields the whole match
+-- Used by 'RH.sub' and 'RH.gsub'
+--
+-- Requires "Text.Show.Functions"
+--
+-- >>> :m + Text.Show.Functions
+-- >>> pz @(ReplaceAll "\\." (ReplaceFn2 (Fst Id)) (Snd Id)) (\x -> x <> ":" <> x, "141.201.1.22")
+-- PresentT "141.:.201.:.1.:.22"
+--
+data ReplaceFn2 p
+
+instance (PP p x ~ (String -> String)
+        , P p x) => P (ReplaceFn2 p) x where
+  type PP (ReplaceFn2 p) x = RReplace
+  eval _ opts x = do
+    let msg0 = "ReplaceFn2 (String -> String)"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right f -> mkNode opts (PresentT (RReplace2 f)) msg0 [hh pp]
+
+-- | A replacement function @([String] -> String)@ which yields the groups
+-- Used by 'RH.sub' and 'RH.gsub'
+--
+-- Requires "Text.Show.Functions"
+--
+-- >>> :m + Text.Show.Functions
+-- >>> import Data.List (intercalate)
+-- >>> pz @(ReplaceAll "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" (ReplaceFn3 (Fst Id)) (Snd Id)) (\ys -> intercalate  " | " $ map (show . succ . readNote @Int "invalid int") ys, "141.201.1.22")
+-- PresentT "142 | 202 | 2 | 23"
+--
+data ReplaceFn3 p
+
+instance (PP p x ~ ([String] -> String)
+        , P p x) => P (ReplaceFn3 p) x where
+  type PP (ReplaceFn3 p) x = RReplace
+  eval _ opts x = do
+    let msg0 = "ReplaceFn3 ([String] -> String)"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right f -> mkNode opts (PresentT (RReplace3 f)) msg0 [hh pp]
+ src/Predicate/Data/String.hs view
@@ -0,0 +1,429 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted String functions
+-}
+module Predicate.Data.String (
+    TrimBoth
+  , TrimL
+  , TrimR
+  , StripR
+  , StripL
+
+  , IsPrefix
+  , IsInfix
+  , IsSuffix
+  , IsPrefixI
+  , IsInfixI
+  , IsSuffixI
+
+  , ToString
+  , FromString
+  , FromString'
+ ) where
+import Predicate.Core
+import Predicate.Util
+import qualified GHC.TypeLits as GL
+import Control.Lens hiding (iall)
+import Data.List
+import qualified Data.Text.Lens as DTL
+import Data.Proxy
+import Data.Kind (Type)
+import Data.String
+import Data.Char
+import Data.Function
+import qualified Data.ByteString.Char8 as BS8
+import qualified Data.ByteString.Lazy.Char8 as BL8
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import qualified Data.Text as T
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Sequence as Seq
+
+-- | similar to 'T.strip' 'T.stripStart' 'T.stripEnd'
+--
+-- >>> pz @(TrimBoth (Snd Id)) (20," abc   " :: String)
+-- PresentT "abc"
+--
+-- >>> pz @(TrimBoth (Snd Id)) (20,T.pack " abc   ")
+-- PresentT "abc"
+--
+-- >>> pz @(TrimL (Snd Id)) (20," abc   ")
+-- PresentT "abc   "
+--
+-- >>> pz @(TrimR (Snd Id)) (20," abc   ")
+-- PresentT " abc"
+--
+-- >>> pz @(TrimR "  abc ") ()
+-- PresentT "  abc"
+--
+-- >>> pz @(TrimR "") ()
+-- PresentT ""
+--
+-- >>> pz @(TrimBoth "         ") ()
+-- PresentT ""
+--
+-- >>> pz @(TrimBoth "") ()
+-- PresentT ""
+--
+data TrimImpl (left :: Bool) (right :: Bool) p
+
+instance (FailUnlessT (OrT l r)
+           ('GL.Text "TrimImpl: left and right cannot both be False")
+        , GetBool l
+        , GetBool r
+        , DTL.IsText (PP p x)
+        , P p x
+        ) => P (TrimImpl l r p) x where
+  type PP (TrimImpl l r p) x = PP p x
+  eval _ opts x = do
+    let msg0 = "Trim" ++ (if l && r then "Both" else if l then "L" else "R")
+        l = getBool @l
+        r = getBool @r
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right (view DTL.unpacked -> p) ->
+        let fl = if l then dropWhile isSpace else id
+            fr = if r then dropWhileEnd isSpace else id
+            b =  (fl . fr) p
+        in mkNode opts (PresentT (b ^. DTL.packed)) (msg0 <> litL opts b <> litVerbose opts " | " p) [hh pp]
+
+-- | similar to 'T.stripStart'
+--
+-- >>> pz @(TrimL (Snd Id)) (20," abc   ")
+-- PresentT "abc   "
+--
+data TrimL p
+type TrimLT p = TrimImpl 'True 'False p
+
+instance P (TrimLT p) x => P (TrimL p) x where
+  type PP (TrimL p) x = PP (TrimLT p) x
+  eval _ = eval (Proxy @(TrimLT p))
+
+-- | similar to 'T.stripEnd'
+--
+-- >>> pz @(TrimR (Snd Id)) (20," abc   ")
+-- PresentT " abc"
+--
+-- >>> pz @(TrimR "  abc ") ()
+-- PresentT "  abc"
+--
+-- >>> pz @(TrimR "") ()
+-- PresentT ""
+--
+data TrimR p
+type TrimRT p = TrimImpl 'False 'True p
+
+instance P (TrimRT p) x => P (TrimR p) x where
+  type PP (TrimR p) x = PP (TrimRT p) x
+  eval _ = eval (Proxy @(TrimRT p))
+
+-- | similar to 'T.strip'
+--
+-- >>> pz @(TrimBoth (Snd Id)) (20," abc   " :: String)
+-- PresentT "abc"
+--
+-- >>> pz @(TrimBoth (Snd Id)) (20,T.pack " abc   ")
+-- PresentT "abc"
+--
+-- >>> pz @(TrimBoth "         ") ()
+-- PresentT ""
+--
+-- >>> pz @(TrimBoth "") ()
+-- PresentT ""
+--
+data TrimBoth p
+type TrimBothT p = TrimImpl 'True 'True p
+
+instance P (TrimBothT p) x => P (TrimBoth p) x where
+  type PP (TrimBoth p) x = PP (TrimBothT p) x
+  eval _ = eval (Proxy @(TrimBothT p))
+
+data StripImpl(left :: Bool) p q
+
+instance (GetBool l
+        , PP p x ~ String
+        , P p x
+        , DTL.IsText (PP q x)
+        , P q x
+        ) => P (StripImpl l p q) x where
+  type PP (StripImpl l p q) x = Maybe (PP q x)
+  eval _ opts x = do
+    let msg0 = "Strip" ++ if l then "L" else "R"
+        l = getBool @l
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
+    pure $ case lr of
+      Left e -> e
+      Right (p,view DTL.unpacked -> q,pp,qq) ->
+        let b = if l then
+                  let (before,after) = splitAt (length p) q
+                  in if before == p then Just after else Nothing
+                else
+                  let (before,after) = splitAt (length q - length p) q
+                  in if after == p then Just before else Nothing
+        in mkNode opts (PresentT (fmap (view DTL.packed) b)) (msg0 <> showL opts b <> litVerbose opts " | p=" p <> litVerbose opts " | q=" q) [hh pp, hh qq]
+
+-- | similar to 'T.stripLeft'
+--
+-- >>> pz @(StripL "xyz" Id) ("xyzHello" :: String)
+-- PresentT (Just "Hello")
+--
+-- >>> pz @(StripL "xyz" Id) (T.pack "xyzHello")
+-- PresentT (Just "Hello")
+--
+-- >>> pz @(StripL "xyz" Id) "xywHello"
+-- PresentT Nothing
+--
+data StripL p q
+type StripLT p q = StripImpl 'True p q
+
+instance P (StripLT p q) x => P (StripL p q) x where
+  type PP (StripL p q) x = PP (StripLT p q) x
+  eval _ = eval (Proxy @(StripLT p q))
+
+-- | similar to 'T.stripRight'
+--
+-- >>> pz @(StripR "xyz" Id) "Hello xyz"
+-- PresentT (Just "Hello ")
+--
+-- >>> pz @(StripR "xyz" Id) "xyzHelloxyw"
+-- PresentT Nothing
+--
+-- >>> pz @(StripR "xyz" Id) ""
+-- PresentT Nothing
+--
+-- >>> pz @(StripR "xyz" "xyz") ()
+-- PresentT (Just "")
+--
+data StripR p q
+type StripRT p q = StripImpl 'False p q
+
+instance P (StripRT p q) x => P (StripR p q) x where
+  type PP (StripR p q) x = PP (StripRT p q) x
+  eval _ = eval (Proxy @(StripRT p q))
+
+-- | similar to 'isInfixOf' 'isPrefixOf' 'isSuffixOf' for strings only.
+--
+-- The \'I\' suffixed versions work are case insensitive.
+--
+-- >>> pz @(IsInfixI "abc" "axAbCd") ()
+-- TrueT
+--
+-- >>> pz @(IsPrefixI "abc" "aBcbCd") ()
+-- TrueT
+--
+-- >>> pz @(IsPrefix "abc" "aBcbCd") ()
+-- FalseT
+--
+-- >>> pz @(IsSuffix "bCd" "aBcbCd") ()
+-- TrueT
+--
+data IsFixImpl (cmp :: Ordering) (ignore :: Bool) p q
+
+instance (GetBool ignore
+        , P p x
+        , P q x
+        , PP p x ~ String
+        , PP q x ~ String
+        , GetOrdering cmp
+        ) => P (IsFixImpl cmp ignore p q) x where
+  type PP (IsFixImpl cmp ignore p q) x = Bool
+  eval _ opts x = do
+    let cmp = getOrdering @cmp
+        ignore = getBool @ignore
+        lwr = if ignore then map toLower else id
+        (ff,msg0) = case cmp of
+                    LT -> (isPrefixOf, "IsPrefix")
+                    EQ -> (isInfixOf, "IsInfix")
+                    GT -> (isSuffixOf, "IsSuffix")
+    pp <- eval (Proxy @p) opts x
+    case getValueLR opts msg0 pp [] of
+        Left e -> pure e
+        Right s0 -> do
+          let msg1 = msg0 <> (if ignore then "I" else "") <> "(" <> s0 <> ")"
+          qq <- eval (Proxy @q) opts x
+          pure $ case getValueLR opts (msg1 <> " q failed") qq [hh pp] of
+            Left e -> e
+            Right s1 -> mkNodeB opts (on ff lwr s0 s1) (msg1 <> " " <> litL opts s1) [hh pp, hh qq]
+
+-- | similar to 'isPrefixOf' for strings
+--
+-- >>> pl @(IsPrefix "xy" Id) "xyzabw"
+-- True (IsPrefix(xy) xyzabw)
+-- TrueT
+--
+-- >>> pl @(IsPrefix "ab" Id) "xyzbaw"
+-- False (IsPrefix(ab) xyzbaw)
+-- FalseT
+--
+data IsPrefix p q
+type IsPrefixT p q = IsFixImpl 'LT 'False p q
+
+instance P (IsPrefixT p q) x => P (IsPrefix p q) x where
+  type PP (IsPrefix p q) x = PP (IsPrefixT p q) x
+  eval _ = evalBool (Proxy @(IsPrefixT p q))
+
+-- | similar to 'isInfixOf' for strings
+--
+-- >>> pl @(IsInfix "ab" Id) "xyzabw"
+-- True (IsInfix(ab) xyzabw)
+-- TrueT
+--
+-- >>> pl @(IsInfix "aB" Id) "xyzAbw"
+-- False (IsInfix(aB) xyzAbw)
+-- FalseT
+--
+-- >>> pl @(IsInfix "ab" Id) "xyzbaw"
+-- False (IsInfix(ab) xyzbaw)
+-- FalseT
+--
+-- >>> pl @(IsInfix (Fst Id) (Snd Id)) ("ab","xyzabw")
+-- True (IsInfix(ab) xyzabw)
+-- TrueT
+--
+
+data IsInfix p q
+type IsInfixT p q = IsFixImpl 'EQ 'False p q
+
+instance P (IsInfixT p q) x => P (IsInfix p q) x where
+  type PP (IsInfix p q) x = PP (IsInfixT p q) x
+  eval _ = evalBool (Proxy @(IsInfixT p q))
+
+-- | similar to 'isSuffixOf' for strings
+--
+-- >>> pl @(IsSuffix "bw" Id) "xyzabw"
+-- True (IsSuffix(bw) xyzabw)
+-- TrueT
+--
+-- >>> pl @(IsSuffix "bw" Id) "xyzbaw"
+-- False (IsSuffix(bw) xyzbaw)
+-- FalseT
+--
+data IsSuffix p q
+type IsSuffixT p q = IsFixImpl 'GT 'False p q
+
+instance P (IsSuffixT p q) x => P (IsSuffix p q) x where
+  type PP (IsSuffix p q) x = PP (IsSuffixT p q) x
+  eval _ = evalBool (Proxy @(IsSuffixT p q))
+
+-- | similar to case insensitive 'isPrefixOf' for strings
+--
+data IsPrefixI p q
+type IsPrefixIT p q = IsFixImpl 'LT 'True p q
+
+instance P (IsPrefixIT p q) x => P (IsPrefixI p q) x where
+  type PP (IsPrefixI p q) x = PP (IsPrefixIT p q) x
+  eval _ = evalBool (Proxy @(IsPrefixIT p q))
+
+-- | similar to case insensitive 'isInfixOf' for strings
+--
+-- >>> pl @(IsInfixI "aB" Id) "xyzAbw"
+-- True (IsInfixI(aB) xyzAbw)
+-- TrueT
+--
+data IsInfixI p q
+type IsInfixIT p q = IsFixImpl 'EQ 'True p q
+
+instance P (IsInfixIT p q) x => P (IsInfixI p q) x where
+  type PP (IsInfixI p q) x = PP (IsInfixIT p q) x
+  eval _ = evalBool (Proxy @(IsInfixIT p q))
+
+-- | similar to case insensitive 'isSuffixOf' for strings
+--
+data IsSuffixI p q
+type IsSuffixIT p q = IsFixImpl 'GT 'True p q
+
+instance P (IsSuffixIT p q) x => P (IsSuffixI p q) x where
+  type PP (IsSuffixI p q) x = PP (IsSuffixIT p q) x
+  eval _ = evalBool (Proxy @(IsSuffixIT p q))
+
+-- | very simple conversion to a string
+data ToString p
+instance ( ToStringC (PP p x)
+         , P p x
+         ) => P (ToString p) x where
+  type PP (ToString p) x = String
+  eval _ opts x = do
+    let msg0 = "ToString"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = toStringC p
+        in mkNode opts (PresentT d) msg0 [hh pp]
+
+class ToStringC a where
+  toStringC :: a -> String
+instance ToStringC String where
+  toStringC = id
+instance ToStringC T.Text where
+  toStringC = T.unpack
+instance ToStringC TL.Text where
+  toStringC = TL.unpack
+instance ToStringC BL8.ByteString where
+  toStringC = BL8.unpack
+instance ToStringC BS8.ByteString where
+  toStringC = BS8.unpack
+
+-- | 'fromString' function where you need to provide the type \'t\' of the result
+data FromString' t s
+
+instance (P s a
+        , PP s a ~ String
+        , Show (PP t a)
+        , IsString (PP t a)
+        ) => P (FromString' t s) a where
+  type PP (FromString' t s) a = PP t a
+  eval _ opts a = do
+    let msg0 = "FromString"
+    ss <- eval (Proxy @s) opts a
+    pure $ case getValueLR opts msg0 ss [] of
+      Left e -> e
+      Right s ->
+        let b = fromString @(PP t a) s
+        in mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) [hh ss]
+
+-- | 'fromString' function where you need to provide the type \'t\' of the result
+--
+-- >>> pz @(FromString (Identity _) Id) "abc"
+-- PresentT (Identity "abc")
+--
+-- >>> pz @(FromString (Seq.Seq Char) Id) "abc"
+-- PresentT (fromList "abc")
+--
+data FromString (t :: Type) p
+type FromStringPT (t :: Type) p = FromString' (Hole t) p
+
+instance P (FromStringPT t p) x => P (FromString t p) x where
+  type PP (FromString t p) x = PP (FromStringPT t p) x
+  eval _ = eval (Proxy @(FromStringPT t p))
+
+ src/Predicate/Data/These.hs view
@@ -0,0 +1,1029 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted 'These' functions
+-}
+module Predicate.Data.These (
+ -- ** boolean predicates
+    IsThis
+  , IsThat
+  , IsThese
+
+ -- ** constructors
+  , MkThis
+  , MkThis'
+  , MkThat
+  , MkThat'
+  , MkThese
+
+ -- ** get rid of These
+  , This'
+  , That'
+  , These'
+  , ThisDef
+  , ThisFail
+  , ThatDef
+  , ThatFail
+  , TheseDef
+  , TheseFail
+  , Thiss
+  , Thats
+  , Theses
+  , Theres
+  , Heres
+  , TheseIn
+  , TheseId
+  , PartitionThese
+  , TheseX
+
+ -- ** miscellaneous
+  , ZipThese
+  , Assoc
+  , Unassoc
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Data.Proxy
+import Data.Kind (Type)
+import Data.These (partitionThese, These(..))
+import qualified Data.These.Combinators as TheseC
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+-- >>> import qualified Data.Semigroup as SG
+
+-- | similar to 'partitionThese'. returns a 3-tuple with the results so use 'Fst' 'Snd' 'Thd' to extract
+--
+-- >>> pz @PartitionThese [This 'a', That 2, This 'c', These 'z' 1, That 4, These 'a' 2, That 99]
+-- PresentT ("ac",[2,4,99],[('z',1),('a',2)])
+--
+-- >>> pl @PartitionThese [This 4, That 'x', That 'y',These 3 'b', This 99, These 5 'x']
+-- Present ([4,99],"xy",[(3,'b'),(5,'x')]) (PartitionThese ([4,99],"xy",[(3,'b'),(5,'x')]) | [This 4,That 'x',That 'y',These 3 'b',This 99,These 5 'x'])
+-- PresentT ([4,99],"xy",[(3,'b'),(5,'x')])
+--
+-- >>> pl @PartitionThese [This 1,That 'x',This 4,That 'y',These 9 'z',This 10,These 8 'y']
+-- Present ([1,4,10],"xy",[(9,'z'),(8,'y')]) (PartitionThese ([1,4,10],"xy",[(9,'z'),(8,'y')]) | [This 1,That 'x',This 4,That 'y',These 9 'z',This 10,These 8 'y'])
+-- PresentT ([1,4,10],"xy",[(9,'z'),(8,'y')])
+--
+data PartitionThese
+
+instance ( Show a
+         , Show b
+         ) => P PartitionThese [These a b] where
+  type PP PartitionThese [These a b] = ([a], [b], [(a, b)])
+  eval _ opts as =
+    let msg0 = "PartitionThese"
+        b = partitionThese as
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | similar to 'TheseC.catThis'
+--
+-- >>> pz @(Thiss) [That 1, This 'a', These 'b' 33, This 'd', That 4]
+-- PresentT "ad"
+--
+-- >>> pz @(Thiss) [That 1, This 'a', These 'b' 33]
+-- PresentT "a"
+--
+-- >>> pz @(Thiss) [That 1, That 9, These 1 33]
+-- PresentT []
+--
+data Thiss
+type ThissT = Fst PartitionThese
+
+instance P ThissT x => P Thiss x where
+  type PP Thiss x = PP ThissT x
+  eval _ = eval (Proxy @ThissT)
+
+-- | similar to 'TheseC.catThat'
+--
+-- >>> pl @Thats [This 1, This 10,That 'x', This 99, That 'y']
+-- Present "xy" (Snd "xy" | ([1,10,99],"xy",[]))
+-- PresentT "xy"
+--
+data Thats
+type ThatsT = Snd PartitionThese
+
+instance P ThatsT x => P Thats x where
+  type PP Thats x = PP ThatsT x
+  eval _ = eval (Proxy @ThatsT)
+
+-- | similar to 'TheseC.catThese'
+--
+-- >>> pz @(ZipThese Id (Tail Id) >> Theses) [1..10]
+-- PresentT [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,10)]
+--
+data Theses
+type ThesesT = Thd PartitionThese
+
+instance P ThesesT x => P Theses x where
+  type PP Theses x = PP ThesesT x
+  eval _ = eval (Proxy @ThesesT)
+
+-- | similar to 'TheseC.catHere'
+--
+-- >>> pz @(ZipThese Id (Tail Id) >> Heres) [1..10]
+-- PresentT [1,2,3,4,5,6,7,8,9,10]
+--
+data Heres
+
+instance ( Show a
+         , Show b
+         ) => P Heres [These a b] where
+  type PP Heres [These a b] = [a]
+  eval _ opts as =
+    let msg0 = "Heres"
+        b = TheseC.catHere as
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | similar to 'TheseC.catThere'
+--
+-- >>> pz @(ZipThese Id (Tail Id) >> Theres) [1..10]
+-- PresentT [2,3,4,5,6,7,8,9,10]
+--
+data Theres
+
+instance ( Show a
+         , Show b
+         ) => P Theres [These a b] where
+  type PP Theres [These a b] = [b]
+  eval _ opts as =
+    let msg0 = "Theres"
+        b = TheseC.catThere as
+    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
+
+-- | similar to 'Data.These.mergeTheseWith' but additionally provides \'p\', \'q\' and \'r\' the original input as the first element in the tuple
+--
+-- >>> pz @(TheseX ((Fst (Fst Id) + Snd Id) >> ShowP Id) (ShowP Id) (Snd (Snd Id)) (Snd Id)) (9,This 123)
+-- PresentT "132"
+--
+-- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (This 123)
+-- PresentT (123,"fromthis")
+--
+-- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (That "fromthat")
+-- PresentT (-99,"fromthat")
+--
+-- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (These 123 "fromthese")
+-- PresentT (123,"fromthese")
+--
+-- >>> pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (These @Int 9 "rhs")
+-- Present "a=9 b=rhs" (TheseX(These))
+-- PresentT "a=9 b=rhs"
+--
+-- >>> pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (This @Int 9)
+-- Present "a=10" (TheseX(This))
+-- PresentT "a=10"
+--
+-- >>> pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (That @Int "rhs")
+-- Present "b=rhs" (TheseX(That))
+-- PresentT "b=rhs"
+--
+data TheseX p q r s
+
+instance (P s x
+        , P p (x,a)
+        , P q (x,b)
+        , P r (x,(a,b))
+        , PP s x ~ These a b
+        , PP p (x,a) ~ c
+        , PP q (x,b) ~ c
+        , PP r (x,(a,b)) ~ c
+        ) => P (TheseX p q r s) x where
+  type PP (TheseX p q r s) x = TheseXT (PP s x) x p
+  eval _ opts x = do
+    let msg0 = "TheseX"
+    ss <- eval (Proxy @s) opts x
+    case getValueLR opts msg0 ss [] of
+      Left e -> pure e
+      Right (This a) -> do
+        let msg1 = msg0 <> "(This)"
+        pp <- eval (Proxy @p) opts (x,a)
+        pure $ case getValueLR opts msg1 pp [hh ss] of
+          Left e -> e
+          Right _ -> mkNode opts (_tBool pp) msg1 [hh ss, hh pp]
+      Right (That b) -> do
+        let msg1 = msg0 <> "(That)"
+        qq <- eval (Proxy @q) opts (x,b)
+        pure $ case getValueLR opts msg1 qq [hh ss] of
+          Left e -> e
+          Right _ -> mkNode opts (_tBool qq) msg1 [hh ss, hh qq]
+      Right (These a b) -> do
+        let msg1 = msg0 <> "(These)"
+        rr <- eval (Proxy @r) opts (x,(a,b))
+        pure $ case getValueLR opts msg1 rr [hh ss] of
+          Left e -> e
+          Right _ -> mkNode opts (_tBool rr) msg1 [hh ss, hh rr]
+
+type family TheseXT lr x p where
+  TheseXT (These a b) x p = PP p (x,a)
+
+-- | 'Data.These.This' constructor
+--
+-- >>> pz @(MkThis _ Id) 44
+-- PresentT (This 44)
+--
+-- >>> pz @(Proxy Int >> MkThis' Unproxy 10) []
+-- PresentT (This 10)
+--
+data MkThis' t p
+
+instance ( Show (PP p x)
+         , P p x
+         ) => P (MkThis' t p) x where
+  type PP (MkThis' t p) x = These (PP p x) (PP t x)
+  eval _ opts x = do
+    let msg0 = "MkThis"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = This p
+        in mkNode opts (PresentT d) (msg0 <> " This " <> showL opts p) [hh pp]
+
+-- | 'Data.These.This' constructor
+--
+-- >>> pl @(MkThis () Id) 'x'
+-- Present This 'x' (MkThis This 'x')
+-- PresentT (This 'x')
+--
+-- >>> pl @(MkThis () (Fst Id)) ('x',True)
+-- Present This 'x' (MkThis This 'x')
+-- PresentT (This 'x')
+--
+
+data MkThis (t :: Type) p
+type MkThisT (t :: Type) p = MkThis' (Hole t) p
+
+instance P (MkThisT t p) x => P (MkThis t p) x where
+  type PP (MkThis t p) x = PP (MkThisT t p) x
+  eval _ = eval (Proxy @(MkThisT t p))
+
+-- | 'Data.These.That' constructor
+--
+-- >>> pz @(MkThat _ Id) 44
+-- PresentT (That 44)
+--
+-- >>> pz @(MkThat _ "Abc" <> MkThis _ '[1,2] <> MkThese [3,4] "def") ()
+-- PresentT (These [1,2,3,4] "Abcdef")
+--
+-- >>> pl @(MkThat () Id) 'x'
+-- Present That 'x' (MkThat That 'x')
+-- PresentT (That 'x')
+--
+data MkThat' t p
+
+instance ( Show (PP p x)
+         , P p x
+         ) => P (MkThat' t p) x where
+  type PP (MkThat' t p) x = These (PP t x) (PP p x)
+  eval _ opts x = do
+    let msg0 = "MkThat"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let d = That p
+        in mkNode opts (PresentT d) (msg0 <> " That " <> showL opts p) [hh pp]
+
+data MkThat (t :: Type) p
+type MkThatT (t :: Type) p = MkThat' (Hole t) p
+
+instance P (MkThatT t p) x => P (MkThat t p) x where
+  type PP (MkThat t p) x = PP (MkThatT t p) x
+  eval _ = eval (Proxy @(MkThatT t p))
+
+-- type MkThat t p = MkThis t p >> Swap
+-- type MkThat' (t :: Type) = Pure (These t) Id -- t has to be a semigroup
+
+-- | 'Data.These.These' constructor
+--
+-- >>> pz @(MkThese (Fst Id) (Snd Id)) (44,'x')
+-- PresentT (These 44 'x')
+--
+-- >>> pl @(MkThese Id 'True) 'x'
+-- Present These 'x' True (MkThese These 'x' True)
+-- PresentT (These 'x' True)
+--
+data MkThese p q
+instance (P p a
+        , P q a
+        , Show (PP p a)
+        , Show (PP q a)
+        ) => P (MkThese p q) a where
+  type PP (MkThese p q) a = These (PP p a) (PP q a)
+  eval _ opts a = do
+    let msg0 = "MkThese"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let d = These p q
+        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts d) [hh pp, hh qq]
+
+-- | predicate on 'These'
+--
+-- >>> pz @(IsThis Id) (This "aBc")
+-- TrueT
+--
+-- >>> pz @(IsThis Id) (These 1 'a')
+-- FalseT
+--
+-- >>> pz @(IsThese Id) (These 1 'a')
+-- TrueT
+--
+-- >>> pl @(IsThat Id) (This 12)
+-- False (IsThat | This 12)
+-- FalseT
+--
+-- >>> pl @(IsThis Id) (This 12)
+-- True (IsThis | This 12)
+-- TrueT
+--
+-- >>> pl @(IsThese Id) (This 12)
+-- False (IsThese | This 12)
+-- FalseT
+--
+-- >>> pl @(IsThese Id) (These 'x' 12)
+-- True (IsThese | These 'x' 12)
+-- TrueT
+--
+-- >>> pl @(IsThese Id) (That (SG.Sum 12))
+-- False (IsThese | That (Sum {getSum = 12}))
+-- FalseT
+--
+-- >>> pl @(IsThese Id) (These 1 (SG.Sum 12))
+-- True (IsThese | These 1 (Sum {getSum = 12}))
+-- TrueT
+--
+
+data IsTh (th :: These x y) p -- x y can be anything
+
+-- trying to avoid show instance cos of ambiguities
+instance (PP p x ~ These a b
+        , P p x
+        , Show a
+        , Show b
+        , GetThese th
+        ) => P (IsTh (th :: These x1 x2) p) x where
+  type PP (IsTh th p) x = Bool
+  eval _ opts x = do
+    let msg0 = "Is"
+    pp <- eval (Proxy @p) opts x
+    pure $ case getValueLR opts msg0 pp [] of
+      Left e -> e
+      Right p ->
+        let (t,f) = getThese @th
+            b = f p
+        in mkNodeB opts b (msg0 <> t <> showVerbose opts " | " p) [hh pp]
+
+data IsThis p
+type IsThisT p = IsTh ('This '()) p
+
+instance P (IsThisT p) x => P (IsThis p) x where
+  type PP (IsThis p) x = PP (IsThisT p) x
+  eval _ = evalBool (Proxy @(IsThisT p))
+
+data IsThat p
+type IsThatT p = IsTh ('That '()) p
+
+instance P (IsThatT p) x => P (IsThat p) x where
+  type PP (IsThat p) x = PP (IsThatT p) x
+  eval _ = evalBool (Proxy @(IsThatT p))
+
+data IsThese p
+type IsTheseT p = IsTh ('These '() '()) p
+
+instance P (IsTheseT p) x => P (IsThese p) x where
+  type PP (IsThese p) x = PP (IsTheseT p) x
+  eval _ = evalBool (Proxy @(IsTheseT p))
+
+-- | similar to 'Data.These.these'
+--
+-- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (This 13)
+-- PresentT 13
+--
+-- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (That "this is a long string")
+-- PresentT 21
+--
+-- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (These 20 "somedata")
+-- PresentT 28
+--
+-- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (That "this is a long string")
+-- PresentT (Right "this is a long string")
+--
+-- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (These 1 "this is a long string")
+-- PresentT (Right "this is a long string")
+--
+-- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (These 100 "this is a long string")
+-- PresentT (Left 100)
+--
+-- >>> pl @(TheseIn "this" "that" "these") (This (SG.Sum 12))
+-- Present "this" (TheseIn "this" | This Sum {getSum = 12})
+-- PresentT "this"
+--
+-- >>> pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (These "Ab" 13)
+-- Present ("Ab",13) (TheseIn ("Ab",13) | These "Ab" 13)
+-- PresentT ("Ab",13)
+--
+-- >>> pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (This "Ab")
+-- Present ("Ab",999) (TheseIn ("Ab",999) | This "Ab")
+-- PresentT ("Ab",999)
+--
+-- >>> pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (That 13)
+-- Present ("no value",13) (TheseIn ("no value",13) | That 13)
+-- PresentT ("no value",13)
+--
+
+data TheseIn p q r
+
+instance (Show a
+        , Show b
+        , Show (PP p a)
+        , P p a
+        , P q b
+        , P r (a,b)
+        , PP p a ~ PP q b
+        , PP p a ~ PP r (a,b)
+        , PP q b ~ PP r (a,b)
+         )  => P (TheseIn p q r) (These a b) where
+  type PP (TheseIn p q r) (These a b) = PP p a
+  eval _ opts th = do
+     let msg0 = "TheseIn"
+     case th of
+        This a -> do
+          let msg1 = "This "
+              msg2 = msg0 <> msg1
+          pp <- eval (Proxy @p) opts a
+          pure $ case getValueLR opts (msg2 <> "p failed") pp [] of
+               Left e -> e
+               Right c -> mkNode opts (PresentT c) (show01' opts msg0 c msg1 a) [hh pp]
+        That b -> do
+          let msg1 = "That "
+              msg2 = msg0 <> msg1
+          qq <- eval (Proxy @q) opts b
+          pure $ case getValueLR opts (msg2 <> "q failed") qq [] of
+               Left e -> e
+               Right c -> mkNode opts (PresentT c) (show01' opts msg0 c msg1 b) [hh qq]
+        These a b -> do
+          let msg1 = "These "
+              msg2 = msg0 <> msg1
+          rr <- eval (Proxy @r) opts (a,b)
+          pure $ case getValueLR opts (msg2 <> "r failed") rr [] of
+               Left e -> e
+               Right c -> mkNode opts (PresentT c) (show01 opts msg0 c (These a b)) [hh rr]
+
+-- | TheseId: returns a tuple so you need to provide a value for rhs in the This case and lhs for the That case
+--
+-- >>> pl @(TheseId 'True "xyz") (This "abc")
+-- Present ("abc",True) (TheseIn ("abc",True) | This "abc")
+-- PresentT ("abc",True)
+--
+-- >>> pl @(TheseId 'True "xyz") (That False)
+-- Present ("xyz",False) (TheseIn ("xyz",False) | That False)
+-- PresentT ("xyz",False)
+--
+-- >>> pl @(TheseId 'True "xyz") (These "abc" False)
+-- Present ("abc",False) (TheseIn ("abc",False) | These "abc" False)
+-- PresentT ("abc",False)
+--
+data TheseId p q
+type TheseIdT p q = TheseIn '(I, p) '(q, I) I
+
+instance P (TheseIdT p q) x => P (TheseId p q) x where
+  type PP (TheseId p q) x = PP (TheseIdT p q) x
+  eval _ = eval (Proxy @(TheseIdT p q))
+
+-- | similar to 'Data.Align.align' thats pads with 'Data.These.This' or 'Data.These.That' if one list is shorter than the other
+--
+-- the key is that all information about both lists are preserved
+--
+-- >>> pz @(ZipThese (Fst Id) (Snd Id)) ("aBc", [1..5])
+-- PresentT [These 'a' 1,These 'B' 2,These 'c' 3,That 4,That 5]
+--
+-- >>> pz @(ZipThese (Fst Id) (Snd Id)) ("aBcDeF", [1..3])
+-- PresentT [These 'a' 1,These 'B' 2,These 'c' 3,This 'D',This 'e',This 'F']
+--
+-- >>> pz @(ZipThese Id Reverse) "aBcDeF"
+-- PresentT [These 'a' 'F',These 'B' 'e',These 'c' 'D',These 'D' 'c',These 'e' 'B',These 'F' 'a']
+--
+-- >>> pz @(ZipThese Id '[]) "aBcDeF"
+-- PresentT [This 'a',This 'B',This 'c',This 'D',This 'e',This 'F']
+--
+-- >>> pz @(ZipThese '[] Id) "aBcDeF"
+-- PresentT [That 'a',That 'B',That 'c',That 'D',That 'e',That 'F']
+--
+-- >>> pz @(ZipThese '[] '[]) "aBcDeF"
+-- PresentT []
+--
+-- >>> pl @(ZipThese (Fst Id) (Snd Id) >> Map (TheseIn Id Id (Fst Id)) Id) (['w'..'y'],['a'..'f'])
+-- Present "wxydef" ((>>) "wxydef" | {Map "wxydef" | [These 'w' 'a',These 'x' 'b',These 'y' 'c',That 'd',That 'e',That 'f']})
+-- PresentT "wxydef"
+--
+-- >>> pl @(("sdf" &&& Id) >> ZipThese (Fst Id) (Snd Id) >> Map (TheseIn (Id &&& 0) (Head "x" &&& Id) Id) Id) [1..5]
+-- Present [('s',1),('d',2),('f',3),('x',4),('x',5)] ((>>) [('s',1),('d',2),('f',3),('x',4),('x',5)] | {Map [('s',1),('d',2),('f',3),('x',4),('x',5)] | [These 's' 1,These 'd' 2,These 'f' 3,That 4,That 5]})
+-- PresentT [('s',1),('d',2),('f',3),('x',4),('x',5)]
+--
+
+data ZipThese p q
+
+instance (PP p a ~ [x]
+        , PP q a ~ [y]
+        , P p a
+        , P q a
+        , Show x
+        , Show y
+        ) => P (ZipThese p q) a where
+  type PP (ZipThese p q) a = [These (ExtractAFromList (PP p a)) (ExtractAFromList (PP q a))]
+  eval _ opts a = do
+    let msg0 = "ZipThese"
+    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
+    pure $ case lr of
+      Left e -> e
+      Right (p,q,pp,qq) ->
+        let hhs = [hh pp, hh qq]
+        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
+          Left e -> e
+          Right () ->
+            let d = simpleAlign p q
+            in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) hhs
+
+
+simpleAlign :: [a] -> [b] -> [These a b]
+simpleAlign as [] = map This as
+simpleAlign [] bs = map That bs
+simpleAlign (a:as) (b:bs) = These a b : simpleAlign as bs
+
+
+-- | extract the This value from an 'These' otherwise use the default value
+--
+-- if there is no This value then \p\ is passed the whole context only
+--
+-- >>> pz @(ThisDef (1 % 4) Id) (This 20.4)
+-- PresentT (102 % 5)
+--
+-- >>> pz @(ThisDef (1 % 4) Id) (That "aa")
+-- PresentT (1 % 4)
+--
+-- >>> pz @(ThisDef (1 % 4) Id) (These 2.3 "aa")
+-- PresentT (1 % 4)
+--
+-- >>> pz @(ThisDef (PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id)) (Snd Id)) (123,That "xy")
+-- PresentT "found That \"xy\" fst=123"
+--
+-- >>> pz @(ThisDef (MEmptyT _) Id) (That 222)
+-- PresentT ()
+--
+-- >>> pz @(ThisDef (MEmptyT (SG.Sum _)) Id) (These 222 'x')
+-- PresentT (Sum {getSum = 0})
+--
+-- >>> pl @(ThisDef (MEmptyT _) Id) (This (SG.Sum 12))
+-- Present Sum {getSum = 12} (ThisDef This)
+-- PresentT (Sum {getSum = 12})
+--
+-- >>> pl @(ThisDef (MEmptyT _) Id) (That 12)
+-- Present () (ThisDef That)
+-- PresentT ()
+--
+
+data ThisDef p q
+
+instance ( PP q x ~ These a b
+         , PP p x ~ a
+         , P q x
+         , P p x
+    ) => P (ThisDef p q) x where
+  type PP (ThisDef p q) x = ThisT (PP q x)
+  eval _ opts x = do
+    let msg0 = "ThisDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          This a -> pure $ mkNode opts (PresentT a) (msg0 <> " This") [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+
+-- | extract the That value from an 'These' otherwise use the default value
+--
+-- if there is no That value then \p\ is passed the whole context only
+--
+-- >>> pz @(ThatDef (1 % 4) Id) (That 20.4)
+-- PresentT (102 % 5)
+--
+-- >>> pz @(ThatDef (1 % 4) Id) (This "aa")
+-- PresentT (1 % 4)
+--
+-- >>> pz @(ThatDef (1 % 4) Id) (These "aa" 2.3)
+-- PresentT (1 % 4)
+--
+-- >>> pz @(ThatDef (PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id)) (Snd Id)) (123,This "xy")
+-- PresentT "found This \"xy\" fst=123"
+--
+-- >>> pz @(ThatDef (MEmptyT _) Id) (This 222)
+-- PresentT ()
+--
+-- >>> pz @(ThatDef (MEmptyT (SG.Sum _)) Id) (These 'x' 1120)
+-- PresentT (Sum {getSum = 0})
+--
+data ThatDef p q
+
+instance ( PP q x ~ These a b
+         , PP p x ~ b
+         , P q x
+         , P p x
+    ) => P (ThatDef p q) x where
+  type PP (ThatDef p q) x = ThatT (PP q x)
+  eval _ opts x = do
+    let msg0 = "ThatDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          That a -> pure $ mkNode opts (PresentT a) (msg0 <> " That") [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+-- | extract the These value from an 'These' otherwise use the default value
+--
+-- if there is no These value then \p\ is passed the whole context only
+--
+-- >>> pz @(TheseDef '(1 % 4,"zz") Id) (These 20.4 "x")
+-- PresentT (102 % 5,"x")
+--
+-- >>> pz @(TheseDef '(1 % 4,"zz") Id) (This 20.4)
+-- PresentT (1 % 4,"zz")
+--
+-- >>> pz @(TheseDef '(1 % 4,"zz") Id) (That "x")
+-- PresentT (1 % 4,"zz")
+--
+-- >>> pz @(TheseDef '(PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id),999) (Snd Id)) (123,This "xy")
+-- PresentT ("found This \"xy\" fst=123",999)
+--
+-- >>> pz @(TheseDef (MEmptyT (SG.Sum _, String)) Id) (This 222)
+-- PresentT (Sum {getSum = 0},"")
+--
+-- >>> pz @(TheseDef (MEmptyT _) Id) (These (222 :: SG.Sum Int) "aa")
+-- PresentT (Sum {getSum = 222},"aa")
+--
+-- >>> pl @(TheseDef '("xyz",'True) Id) (This "abc")
+-- Present ("xyz",True) (TheseDef This)
+-- PresentT ("xyz",True)
+--
+-- >>> pl @(TheseDef '("xyz",'True) Id) (That False)
+-- Present ("xyz",True) (TheseDef That)
+-- PresentT ("xyz",True)
+--
+-- >>> pl @(TheseDef '("xyz",'True) Id) (These "abc" False)
+-- Present ("abc",False) (TheseDef These)
+-- PresentT ("abc",False)
+--
+data TheseDef p q
+
+instance ( PP q x ~ These a b
+         , PP p x ~ (a,b)
+         , P q x
+         , P p x
+    ) => P (TheseDef p q) x where
+  type PP (TheseDef p q) x = TheseT (PP q x)
+  eval _ opts x = do
+    let msg0 = "TheseDef"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          These a b -> pure $ mkNode opts (PresentT (a,b)) (msg0 <> " These") [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+
+-- | extract the This value from a 'These' otherwise fail with a message
+--
+-- if there is no This value then \p\ is passed the whole context only
+--
+-- >>> pz @(ThisFail "oops" Id) (This 20.4)
+-- PresentT 20.4
+--
+-- >>> pz @(ThisFail "oops" Id) (That "aa")
+-- FailT "oops"
+--
+-- >>> pz @(ThisFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,That "xy")
+-- FailT "found That \"xy\" fst=123"
+--
+-- >>> pz @(ThisFail (MEmptyT _) Id) (That 222)
+-- FailT ""
+--
+-- >>> pl @(ThisFail "sdf" Id) (This (SG.Sum 12))
+-- Present Sum {getSum = 12} (This)
+-- PresentT (Sum {getSum = 12})
+--
+-- >>> pl @(ThisFail "sdf" Id) (That (SG.Sum 12))
+-- Error sdf (ThisFail That)
+-- FailT "sdf"
+--
+-- >>> pl @(ThisFail "sdf" Id) (That 12)
+-- Error sdf (ThisFail That)
+-- FailT "sdf"
+--
+data ThisFail p q
+
+instance ( PP p x ~ String
+         , PP q x ~ These a b
+         , P p x
+         , P q x)
+    => P (ThisFail p q) x where
+  type PP (ThisFail p q) x = ThisT (PP q x)
+  eval _ opts x = do
+    let msg0 = "ThisFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          This a -> pure $ mkNode opts (PresentT a) "This" [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+
+-- | extract the That value from a 'These' otherwise fail with a message
+--
+-- if there is no That value then \p\ is passed the whole context only
+--
+-- >>> pz @(ThatFail "oops" Id) (That 20.4)
+-- PresentT 20.4
+--
+-- >>> pz @(ThatFail "oops" Id) (This "aa")
+-- FailT "oops"
+--
+-- >>> pz @(ThatFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,This "xy")
+-- FailT "found This \"xy\" fst=123"
+--
+-- >>> pz @(ThatFail (MEmptyT _) Id) (This 222)
+-- FailT ""
+--
+data ThatFail p q
+
+instance ( PP p x ~ String
+         , PP q x ~ These a b
+         , P p x
+         , P q x)
+    => P (ThatFail p q) x where
+  type PP (ThatFail p q) x = ThatT (PP q x)
+  eval _ opts x = do
+    let msg0 = "ThatFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          That a -> pure $ mkNode opts (PresentT a) "That" [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+
+
+
+-- | extract the These value from a 'These' otherwise fail with a message
+--
+-- if there is no These value then \p\ is passed the whole context only
+--
+-- >>> pz @(TheseFail "oops" Id) (These "abc" 20.4)
+-- PresentT ("abc",20.4)
+--
+-- >>> pz @(TheseFail "oops" Id) (That "aa")
+-- FailT "oops"
+--
+-- >>> pz @(TheseFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,That "xy")
+-- FailT "found That \"xy\" fst=123"
+--
+-- >>> pz @(TheseFail (MEmptyT _) Id) (That 222)
+-- FailT ""
+--
+data TheseFail p q
+
+instance ( PP p x ~ String
+         , PP q x ~ These a b
+         , P p x
+         , P q x)
+    => P (TheseFail p q) x where
+  type PP (TheseFail p q) x = TheseT (PP q x)
+  eval _ opts x = do
+    let msg0 = "TheseFail"
+    qq <- eval (Proxy @q) opts x
+    case getValueLR opts msg0 qq [] of
+      Left e -> pure e
+      Right q ->
+        case q of
+          These a b -> pure $ mkNode opts (PresentT (a,b)) "These" [hh qq]
+          _ -> do
+            pp <- eval (Proxy @p) opts x
+            pure $ case getValueLR opts msg0 pp [hh qq] of
+              Left e -> e
+              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
+
+
+-- | assoc using 'AssocC'
+--
+-- >>> pz @Assoc (This (These 123 'x'))
+-- PresentT (These 123 (This 'x'))
+--
+-- >>> pz @Assoc ((99,'a'),True)
+-- PresentT (99,('a',True))
+--
+-- >>> pz @Assoc ((99,'a'),True)
+-- PresentT (99,('a',True))
+--
+-- >>> pz @Assoc (Right "Abc" :: Either (Either () ()) String)
+-- PresentT (Right (Right "Abc"))
+--
+-- >>> pz @Assoc (Left (Left 'x'))
+-- PresentT (Left 'x')
+--
+-- >>> pl @Assoc ((10,'c'),True)
+-- Present (10,('c',True)) (Assoc (10,('c',True)) | ((10,'c'),True))
+-- PresentT (10,('c',True))
+--
+-- >>> pl @(Assoc >> Unassoc) ((10,'c'),True)
+-- Present ((10,'c'),True) ((>>) ((10,'c'),True) | {Unassoc ((10,'c'),True) | (10,('c',True))})
+-- PresentT ((10,'c'),True)
+--
+data Assoc
+
+class AssocC p where
+  assoc :: p (p a b) c -> p a (p b c)
+  unassoc :: p a (p b c) -> p (p a b) c
+instance AssocC Either where
+  assoc (Left (Left a)) = Left a
+  assoc (Left (Right b)) = Right (Left b)
+  assoc (Right b) = Right (Right b)
+  unassoc (Left a) = Left (Left a)
+  unassoc (Right (Left b)) = Left (Right b)
+  unassoc (Right (Right b)) = Right b
+instance AssocC These where
+  assoc (This (This a)) = This a
+  assoc (This (That b)) = That (This b)
+  assoc (That b) = That (That b)
+  assoc (These (This a) c) = These a (That c)
+  assoc (These (That b) c) = That (These b c)
+  assoc (These (These a b) c) = These a (These b c)
+  assoc (This (These a b)) = These a (This b)
+  unassoc (This a) = This (This a)
+  unassoc (That (This b)) = This (That b)
+  unassoc (That (That b)) = That b
+  unassoc (These a (That c)) = These (This a) c
+  unassoc (That (These b c)) = These (That b) c
+  unassoc (These a (These b c)) = These (These a b) c
+  unassoc (These a (This b)) = This (These a b)
+
+instance AssocC (,) where
+  assoc ((a,b),c) = (a,(b,c))
+  unassoc (a,(b,c)) = ((a,b),c)
+
+instance (Show (p (p a b) c)
+        , Show (p a (p b c))
+        , AssocC p
+        ) => P Assoc (p (p a b) c) where
+  type PP Assoc (p (p a b) c) = p a (p b c)
+  eval _ opts pabc =
+    let msg0 = "Assoc"
+        d = assoc pabc
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabc) []
+
+-- | unassoc using 'AssocC'
+--
+-- >>> pz @Unassoc (These 123 (This 'x'))
+-- PresentT (This (These 123 'x'))
+--
+-- >>> pz @Unassoc (99,('a',True))
+-- PresentT ((99,'a'),True)
+--
+-- >>> pz @Unassoc (This 10 :: These Int (These Bool ()))
+-- PresentT (This (This 10))
+--
+-- >>> pz @Unassoc (Right (Right 123))
+-- PresentT (Right 123)
+--
+-- >>> pz @Unassoc (Left 'x' :: Either Char (Either Bool Double))
+-- PresentT (Left (Left 'x'))
+--
+-- >>> pl @Unassoc (10,('c',True))
+-- Present ((10,'c'),True) (Unassoc ((10,'c'),True) | (10,('c',True)))
+-- PresentT ((10,'c'),True)
+--
+data Unassoc
+
+instance (Show (p (p a b) c)
+        , Show (p a (p b c))
+        , AssocC p
+        ) => P Unassoc (p a (p b c)) where
+  type PP Unassoc (p a (p b c)) = p (p a b) c
+  eval _ opts pabc =
+    let msg0 = "Unassoc"
+        d = unassoc pabc
+    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabc) []
+
+
+-- | tries to extract a value from the 'Data.These.This' constructor
+--
+-- >>> pz @(This' >> Succ Id) (This 20)
+-- PresentT 21
+--
+-- >>> pz @(This' >> Succ Id) (That 'a')
+-- FailT "This' found That"
+--
+data This'
+instance (Show a
+        ) => P This' (These a x) where
+  type PP This' (These a x) = a
+  eval _ opts lr =
+    let msg0 = "This'"
+    in pure $ case lr of
+         These _ _ -> mkNode opts (FailT (msg0 <> " found These")) "" []
+         That _ -> mkNode opts (FailT (msg0 <> " found That")) "" []
+         This a -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | tries to extract a value from the 'Data.These.That' constructor
+--
+-- >>> pz @(That' >> Succ Id) (That 20)
+-- PresentT 21
+--
+-- >>> pz @(That' >> Succ Id) (This 'a')
+-- FailT "That' found This"
+--
+data That'
+instance (Show a
+        ) => P That' (These x a) where
+  type PP That' (These x a) = a
+  eval _ opts lr =
+    let msg0 = "That'"
+    in pure $ case lr of
+         These _ _ -> mkNode opts (FailT (msg0 <> " found These")) "" []
+         This _ -> mkNode opts (FailT (msg0 <> " found This")) "" []
+         That a -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
+
+-- | tries to extract the values from the 'Data.These.These' constructor
+--
+-- >>> pz @(These' >> Second (Succ Id)) (These 1 'a')
+-- PresentT (1,'b')
+--
+-- >>> pz @(That' >> Succ Id) (This 'a')
+-- FailT "That' found This"
+--
+-- >>> pz @(These' >> Second (Succ Id)) (That 8)
+-- FailT "These' found That"
+--
+data These'
+instance (Show a, Show b
+        ) => P These' (These a b) where
+  type PP These' (These a b) = (a,b)
+  eval _ opts lr =
+    let msg0 = "These'"
+    in pure $ case lr of
+         This _ -> mkNode opts (FailT (msg0 <> " found This")) "" []
+         That _ -> mkNode opts (FailT (msg0 <> " found That")) "" []
+         These a b -> mkNode opts (PresentT (a,b)) (msg0 <> " " <> showL opts (a,b)) []
+
+
+ src/Predicate/Data/Tuple.hs view
@@ -0,0 +1,324 @@+{-# OPTIONS -Wall #-}
+{-# OPTIONS -Wno-compat #-}
+{-# OPTIONS -Wincomplete-record-updates #-}
+{-# OPTIONS -Wincomplete-uni-patterns #-}
+{-# OPTIONS -Wredundant-constraints #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE NoOverloadedLists #-}
+{-# LANGUAGE NoStarIsType #-}
+{- |
+     promoted tuple functions
+-}
+module Predicate.Data.Tuple (
+
+    Dup
+  , First
+  , Second
+  , type (&&&)
+  , type (***)
+  , Pairs
+
+  , AndA
+  , type (&*)
+  , OrA
+  , type (|+)
+
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Data.Proxy
+
+-- $setup
+-- >>> :set -XDataKinds
+-- >>> :set -XTypeApplications
+-- >>> :set -XTypeOperators
+-- >>> :set -XOverloadedStrings
+-- >>> :set -XNoOverloadedLists
+-- >>> import Predicate.Prelude
+
+-- | duplicate a value into a tuple
+--
+-- >>> pl @Dup 4
+-- Present (4,4) (W '(4,4))
+-- PresentT (4,4)
+--
+-- >>> pl @(Dup >> Id) 4
+-- Present (4,4) ((>>) (4,4) | {Id (4,4)})
+-- PresentT (4,4)
+--
+-- >>> pl @(Dup << Fst Id * Snd Id) (4,5)
+-- Present (20,20) ((>>) (20,20) | {W '(20,20)})
+-- PresentT (20,20)
+--
+-- >>> pl @(Fst Id * Snd Id >> Dup) (4,5)
+-- Present (20,20) ((>>) (20,20) | {W '(20,20)})
+-- PresentT (20,20)
+--
+data Dup
+type DupT = W '(Id, Id)
+
+instance Show x => P Dup x where
+  type PP Dup x = PP DupT x
+  eval _ = eval (Proxy @DupT)
+
+-- | creates a list of overlapping pairs of elements. requires two or more elements
+--
+-- >>> pz @Pairs [1,2,3,4]
+-- PresentT [(1,2),(2,3),(3,4)]
+--
+-- >>> pz @Pairs []
+-- FailT "Pairs no data found"
+--
+-- >>> pz @Pairs [1]
+-- FailT "Pairs only one element found"
+--
+-- >>> pl @Pairs ([] :: [()])
+-- Error Pairs no data found (Pairs no data found)
+-- FailT "Pairs no data found"
+--
+-- >>> pl @Pairs [1]
+-- Error Pairs only one element found (Pairs only one element found)
+-- FailT "Pairs only one element found"
+--
+-- >>> pl @Pairs [1,2]
+-- Present [(1,2)] (Pairs [(1,2)] | [1,2])
+-- PresentT [(1,2)]
+--
+-- >>> pl @Pairs [1,2,3]
+-- Present [(1,2),(2,3)] (Pairs [(1,2),(2,3)] | [1,2,3])
+-- PresentT [(1,2),(2,3)]
+--
+-- >>> pl @Pairs [1,2,3,4]
+-- Present [(1,2),(2,3),(3,4)] (Pairs [(1,2),(2,3),(3,4)] | [1,2,3,4])
+-- PresentT [(1,2),(2,3),(3,4)]
+--
+data Pairs
+instance Show a => P Pairs [a] where
+  type PP Pairs [a] = [(a,a)]
+  eval _ opts as =
+    let msg0 = "Pairs"
+        lr = case as of
+               [] -> Left (msg0 <> " no data found")
+               [_] -> Left (msg0 <> " only one element found")
+               _:bs@(_:_) -> Right (zip as bs)
+    in pure $ case lr of
+         Left e -> mkNode opts (FailT e) e []
+         Right zs -> mkNode opts (PresentT zs) (show01 opts msg0 zs as ) []
+
+
+-- | similar to 'Control.Arrow.&&&'
+--
+-- >>> pl @(Min &&& Max >> Id >> Fst Id < Snd Id) [10,4,2,12,14]
+-- True ((>>) True | {2 < 14})
+-- TrueT
+--
+-- >>> pl @((123 &&& Id) >> Fst Id + Snd Id) 4
+-- Present 127 ((>>) 127 | {123 + 4 = 127})
+-- PresentT 127
+--
+-- >>> pl @(4 &&& "sadf" &&& 'LT) ()
+-- Present (4,("sadf",LT)) (W '(4,("sadf",LT)))
+-- PresentT (4,("sadf",LT))
+--
+-- >>> pl @(Id &&& '() &&& ()) (Just 10)
+-- Present (Just 10,((),())) (W '(Just 10,((),())))
+-- PresentT (Just 10,((),()))
+--
+-- >>> pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,'x',True)
+-- Present (1,('x',(True,()))) (W '(1,('x',(True,()))))
+-- PresentT (1,('x',(True,())))
+--
+-- >>> pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,'x',True)
+-- Present (1,('x',(True,()))) (W '(1,('x',(True,()))))
+-- PresentT (1,('x',(True,())))
+--
+-- >>> pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,1.4,"aaa")
+-- Present (1,(1.4,("aaa",()))) (W '(1,(1.4,("aaa",()))))
+-- PresentT (1,(1.4,("aaa",())))
+--
+data p &&& q
+infixr 3 &&&
+type WAmpT p q = W '(p, q)
+
+instance P (WAmpT p q) x => P (p &&& q) x where
+  type PP (p &&& q) x = PP (WAmpT p q) x
+  eval _ = eval (Proxy @(WAmpT p q))
+
+-- | similar to 'Control.Arrow.***'
+--
+-- >>> pz @(Pred Id *** ShowP Id) (13, True)
+-- PresentT (12,"True")
+--
+-- >>> pl @(FlipT (***) Len (Id * 12)) (99,"cdef")
+-- Present (1188,4) ((***) (1188,4) | (99,"cdef"))
+-- PresentT (1188,4)
+--
+-- >>> pl @(4 *** "sadf" *** 'LT) ('x',("abv",[1]))
+-- Present (4,("sadf",LT)) ((***) (4,("sadf",LT)) | ('x',("abv",[1])))
+-- PresentT (4,("sadf",LT))
+--
+data p *** q
+infixr 3 ***
+
+instance (Show (PP p a)
+        , Show (PP q b)
+        , P p a
+        , P q b
+        , Show a
+        , Show b
+        ) => P (p *** q) (a,b) where
+  type PP (p *** q) (a,b) = (PP p a, PP q b)
+  eval _ opts (a,b) = do
+    let msg0 = "(***)"
+    pp <- eval (Proxy @p) opts a
+    case getValueLR opts msg0 pp [] of
+      Left e -> pure e
+      Right a1 -> do
+        qq <- eval (Proxy @q) opts b
+        pure $ case getValueLR opts msg0 qq [hh pp] of
+          Left e -> e
+          Right b1 -> mkNode opts (PresentT (a1,b1)) (msg0 <> " " <> showL opts (a1,b1) <> showVerbose opts " | " (a,b)) [hh pp, hh qq]
+
+-- | applies a function against the first part of a tuple: similar to 'Control.Arrow.first'
+--
+-- >>> pz @(First (Succ Id)) (12,True)
+-- PresentT (13,True)
+--
+data First p
+type FirstT p = p *** I
+
+instance P (FirstT p) x => P (First p) x where
+  type PP (First p) x = PP (FirstT p) x
+  eval _ = eval (Proxy @(FirstT p))
+
+-- | applies a function against the second part of a tuple: similar to 'Control.Arrow.second'
+--
+-- >>> pz @(Second (Succ Id)) (12,False)
+-- PresentT (12,True)
+--
+data Second q
+type SecondT q = I *** q
+
+instance P (SecondT q) x => P (Second q) x where
+  type PP (Second q) x = PP (SecondT q) x
+  eval _ = eval (Proxy @(SecondT q))
+
+-- | applies \'p\' to lhs of the tuple and \'q\' to the rhs and then \'Ands\' them together
+--
+-- >>> pl @(AndA (Gt 3) (Lt 10) Id) (1,2)
+-- False (False (&*) True | (1 > 3))
+-- FalseT
+--
+data AndA p q r
+instance (PP r x ~ (a,b)
+        , PP p a ~ Bool
+        , PP q b ~ Bool
+        , P p a
+        , P q b
+        , P r x
+        ) => P (AndA p q r) x where
+  type PP (AndA p q r) x = Bool
+  eval _ opts x = do
+    let msg0 = "(&*)"
+    rr <- eval (Proxy @r) opts x
+    case getValueLR opts msg0 rr [] of
+      Left e -> pure e
+      Right (r1,r2) -> do
+        pp <- evalBool (Proxy @p) opts r1
+        case getValueLR opts msg0 pp [hh rr] of
+          Left e -> pure e
+          Right p -> do
+            qq <- evalBool (Proxy @q) opts r2
+            pure $ case getValueLR opts msg0 qq [hh rr, hh pp] of
+              Left e -> e
+              Right q ->
+                let zz = case (p,q) of
+                          (True, True) -> ""
+                          (False, True) -> topMessage pp
+                          (True, False) -> topMessage qq
+                          (False, False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+                in mkNodeB opts (p&&q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh rr, hh pp, hh qq]
+
+-- | applies \'p\' to lhs of the tuple and \'q\' to the rhs and then \'Ands\' them together
+--
+-- >>> pl @(SplitAt 4 "abcdefg" >> Len > 4 &* Len < 5) ()
+-- False ((>>) False | {False (&*) True | (4 > 4)})
+-- FalseT
+--
+data p &* q
+type AndAT p q = AndA p q Id
+infixr 3 &*
+
+instance P (AndAT p q) x => P (p &* q) x where
+  type PP (p &* q) x = PP (AndAT p q) x
+  eval _ = evalBool (Proxy @(AndAT p q))
+
+-- | applies \'p\' to lhs of the tuple and \'q\' to the rhs and then \'Ors\' them together
+--
+-- >>> pl @(OrA (Gt 3) (Lt 10) Id) (1,2)
+-- True (False (|+) True)
+-- TrueT
+--
+data OrA p q r
+instance (PP r x ~ (a,b)
+        , PP p a ~ Bool
+        , PP q b ~ Bool
+        , P p a
+        , P q b
+        , P r x
+        ) => P (OrA p q r) x where
+  type PP (OrA p q r) x = Bool
+  eval _ opts x = do
+    let msg0 = "(|+)"
+    rr <- eval (Proxy @r) opts x
+    case getValueLR opts msg0 rr [] of
+      Left e -> pure e
+      Right (r1,r2) -> do
+        pp <- evalBool (Proxy @p) opts r1
+        case getValueLR opts msg0 pp [hh rr] of
+          Left e -> pure e
+          Right p -> do
+            qq <- evalBool (Proxy @q) opts r2
+            pure $ case getValueLR opts msg0 qq [hh rr, hh pp] of
+              Left e -> e
+              Right q ->
+                let zz = case (p,q) of
+                          (False,False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
+                          _ -> ""
+                in mkNodeB opts (p||q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh rr, hh pp, hh qq]
+
+-- | applies \'p\' to lhs of the tuple and \'q\' to the rhs and then \'Ors\' them together
+--
+-- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,8,14,44],9)
+-- True (True (|+) False)
+-- TrueT
+--
+-- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,14],9)
+-- False (False (|+) False | (32 > 44) (|+) (9 < 2))
+-- FalseT
+--
+-- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,14],1)
+-- True (False (|+) True)
+-- TrueT
+--
+data p |+ q
+type OrAT p q = OrA p q Id
+infixr 3 |+
+
+instance P (OrAT p q) x => P (p |+ q) x where
+  type PP (p |+ q) x = PP (OrAT p q) x
+  eval _ = evalBool (Proxy @(OrAT p q))
src/Predicate/Examples/Common.hs view
@@ -68,10 +68,18 @@   , Ip6op
   , Ip6fmt
 
+  -- ** isbn10
+  , Isbn10ip
+  , Isbn10op
+  , Isbn10fmt
+
+  -- ** isbn13
+  , Isbn13ip
+  , Isbn13op
+  , Isbn13fmt
+
    ) where
-import Predicate.Core
 import Predicate.Prelude
-import Predicate.Util
 import GHC.TypeLits (Nat)
 import Data.Time
 
@@ -166,6 +174,34 @@ 
 -- | \'fmt\' type for formatting an ip6 address
 type Ip6fmt = PrintL 8 "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x" Id
+
+
+type Isbn10ip = Resplit "-" Id
+             >> Concat Id
+             >> 'Just Unsnoc
+             >> Map (ReadP Int (Singleton Id)) Id *** If (Singleton Id ==~ "X") 10 (ReadP Int (Singleton Id))
+
+type Isbn10op = GuardSimple (All (0 <..> 9) (Fst Id) && Between 0 10 (Snd Id))
+             >> ZipWith (Fst Id * Snd Id) (1...10 >> Reverse) (Fst Id +: Snd Id)
+             >> Sum
+             >> Guard "mod 0 oops" (Id `Mod` 11 == 0)
+             >> 'True
+
+type Isbn10fmt = ConcatMap (ShowP Id) Id *** If (Id == 10) "X" (ShowP Id)
+                 >> Fst Id <> "-" <> Snd Id  -- no standard format: just hyphen before checkdigit
+
+
+type Isbn13ip = Resplit "-" Id
+             >> Concat Id
+             >> Map (ReadP Int (Singleton Id)) Id
+
+type Isbn13op = ZipWith (Fst Id * Snd Id) (Cycle 13 [1,3] >> Reverse) Id
+             >> Sum
+             >> '(Id,Id `Mod` 10)
+             >> Guard (PrintT "sum=%d mod 10=%d" Id) (Snd Id == 0)
+             >> 'True
+
+type Isbn13fmt = 'Just Unsnoc >> ConcatMap (ShowP Id) (Fst Id) <> "-" <> ShowP (Snd Id)
 
 -- valid dates for for DateFmts are "2001-01-01" "Jan 24 2009" and "03/29/07"
 type DateFmts = '["%Y-%m-%d", "%m/%d/%y", "%B %d %Y"]
src/Predicate/Examples/Refined1.hs view
@@ -40,10 +40,10 @@ -- >>> :set -XTypeApplications
 -- >>> :set -XTypeOperators
 -- >>> :set -XTemplateHaskell
+-- >>> :m + Data.Ratio
 
--- | tests
+-- | refined1 tests
 --
--- >>> :m + Data.Ratio
 -- >>> newRefined1P (readshow @OZ @Rational) "13 % 3"
 -- Right (Refined1 (13 % 3))
 --
src/Predicate/Examples/Refined2.hs view
@@ -62,6 +62,16 @@   , Ip6
   , Ip6R
 
+  -- ** isbn10
+  , isbn10
+  , Isbn10
+  , Isbn10R
+
+  -- ** isbn13
+  , isbn13
+  , Isbn13
+  , Isbn13R
+
  -- ** base n
   , BaseN
   , BaseN'
@@ -206,7 +216,36 @@ ip6 :: Proxy (Ip6 opts)
 ip6 = Proxy
 
+-- | validate isbn10
+--
+-- >>> newRefined2P (isbn10 @OZ) "0-306-40611-X"
+-- Right (Refined2 {r2In = ([0,3,0,6,4,0,6,1,1],10), r2Out = "0-306-40611-X"})
+--
+-- >>> newRefined2P (isbn10 @OZ) "0-306-40611-9"
+-- Left "Step 2. Failed Boolean Check(op) | mod 0 oops"
+--
+type Isbn10R (opts :: OptT) = MakeR2 (Isbn10 opts)
+type Isbn10 (opts :: OptT) = '(opts, Isbn10ip, Isbn10op, String) -- guards
 
+isbn10 :: Proxy (Isbn10 opts)
+isbn10 = Proxy
+
+-- | validate isbn13
+--
+-- >>> newRefined2P (isbn13 @OZ) "978-0-306-40615-7"
+-- Right (Refined2 {r2In = [9,7,8,0,3,0,6,4,0,6,1,5,7], r2Out = "978-0-306-40615-7"})
+--
+-- >>> newRefined2P (isbn13 @OZ) "978-0-306-40615-8"
+-- Left "Step 2. Failed Boolean Check(op) | sum=101 mod 10=1"
+--
+type Isbn13R (opts :: OptT) = MakeR2 (Isbn13 opts)
+type Isbn13 (opts :: OptT) = '(opts, Isbn13ip, Isbn13op, String) -- guards
+
+isbn13 :: Proxy (Isbn13 opts)
+isbn13 = Proxy
+
+
+
 cc11 :: Proxy (Ccn opts 11)
 cc11 = Proxy
 
@@ -273,7 +312,7 @@ -- Left "Step 2. False Boolean Check(op) | FalseP"
 --
 -- >>> newRefined2 @OL @(ReadP Rational Id) @(Msg (PrintF "invalid=%3.2f" (FromRational Double Id)) (Id > (15 % 1))) "13 % 3"
--- Left "Step 2. False Boolean Check(op) | {invalid=4.3313 % 3 > 15 % 1}"
+-- Left "Step 2. False Boolean Check(op) | {invalid=4.33 13 % 3 > 15 % 1}"
 --
 -- >>> newRefined2 @OZ @(ReadP Rational Id) @(Id > (11 % 1)) "13 % 3"
 -- Left "Step 2. False Boolean Check(op) | FalseP"
src/Predicate/Examples/Refined3.hs view
@@ -36,7 +36,6 @@   , Hms
   , HmsR
 
---  , hms'
   , Hms'
   , HmsR'
 
@@ -68,6 +67,16 @@   , Ip6
   , Ip6R
 
+  -- ** isbn10
+  , isbn10
+  , Isbn10
+  , Isbn10R
+
+  -- ** isbn13
+  , isbn13
+  , Isbn13
+  , Isbn13R
+
  -- ** base n
   , basen
   , base2
@@ -166,7 +175,7 @@ datetime1 = mkProxy3
 
 -- now that time is actually validated we dont need Dtop*
-type DateTime1 (opts :: OptT) (t :: Type) = '( opts, Dtip t, 'True, Dtfmt, String)
+type DateTime1 (opts :: OptT) (t :: Type) = '(opts, Dtip t, 'True, Dtfmt, String)
 
 -- fixed in time-1.9
 -- extra check to validate the time as parseTime doesnt validate the time component
@@ -175,7 +184,7 @@ --    2018-09-14 99:00:96 becomes 2018-09-18 03:01:36
 
 -- valid dates for for DateFmts are "2001-01-01" "Jan 24 2009" and "03/29/07"
-type DateN (opts :: OptT) = '( opts, ParseTimes Day DateFmts Id, 'True, FormatTimeP "%Y-%m-%d" Id, String)
+type DateN (opts :: OptT) = '(opts, ParseTimes Day DateFmts Id, 'True, FormatTimeP "%Y-%m-%d" Id, String)
 
 type DateTimeNR (opts :: OptT) = MakeR3 (DateTimeN opts)
 type DateTimeN (opts :: OptT) = '(opts, ParseTimes UTCTime DateTimeFmts Id, 'True, FormatTimeP "%Y-%m-%d %H:%M:%S" Id, String)
@@ -232,23 +241,51 @@ -- Left "Step 2. Failed Boolean Check(op) | octet 1 out of range 0-255 found 257"
 --
 type Ip4R (opts :: OptT) = MakeR3 (Ip4 opts)
-type Ip4 (opts :: OptT) = '( opts, Ip4ip, Ip4op >> 'True, Ip4fmt, String) -- guards
+type Ip4 (opts :: OptT) = '(opts, Ip4ip, Ip4op >> 'True, Ip4fmt, String) -- guards
 
 ip4 :: OptTC opts => Proxy (Ip4 opts)
 ip4 = mkProxy3'
 
 type Ip4R' (opts :: OptT) = MakeR3 (Ip4' opts)
-type Ip4' (opts :: OptT) = '( opts, Ip4ip, Ip4op', Ip4fmt, String) -- boolean predicates
+type Ip4' (opts :: OptT) = '(opts, Ip4ip, Ip4op', Ip4fmt, String) -- boolean predicates
 
 ip4' :: OptTC opts => Proxy (Ip4' opts)
 ip4' = mkProxy3'
 
 type Ip6R (opts :: OptT) = MakeR3 (Ip6 opts)
-type Ip6 (opts :: OptT) = '( opts, Ip6ip, Ip6op, Ip6fmt, String) -- guards
+type Ip6 (opts :: OptT) = '(opts, Ip6ip, Ip6op, Ip6fmt, String) -- guards
 
 ip6 :: Proxy (Ip6 opts)
 ip6 = Proxy
 
+-- | validate isbn10
+--
+-- >>> newRefined3P (isbn10 @OZ) "0-306-40611-X"
+-- Right (Refined3 {r3In = ([0,3,0,6,4,0,6,1,1],10), r3Out = "030640611-X"})
+--
+-- >>> newRefined3P (isbn10 @OZ) "0-306-40611-9"
+-- Left "Step 2. Failed Boolean Check(op) | mod 0 oops"
+--
+type Isbn10R (opts :: OptT) = MakeR3 (Isbn10 opts)
+type Isbn10 (opts :: OptT) = '(opts, Isbn10ip, Isbn10op, Isbn10fmt, String) -- guards
+
+isbn10 :: Proxy (Isbn10 opts)
+isbn10 = Proxy
+
+-- | validate isbn13
+--
+-- >>> newRefined3P (isbn13 @OZ) "978-0-306-40615-7"
+-- Right (Refined3 {r3In = [9,7,8,0,3,0,6,4,0,6,1,5,7], r3Out = "978030640615-7"})
+--
+-- >>> newRefined3P (isbn13 @OZ) "978-0-306-40615-8"
+-- Left "Step 2. Failed Boolean Check(op) | sum=101 mod 10=1"
+--
+type Isbn13R (opts :: OptT) = MakeR3 (Isbn13 opts)
+type Isbn13 (opts :: OptT) = '(opts, Isbn13ip, Isbn13op, Isbn13fmt, String) -- guards
+
+isbn13 :: Proxy (Isbn13 opts)
+isbn13 = Proxy
+
 -- | convert a string from a given base \'i\' and store it internally as an base 10 integer
 --
 -- >>> newRefined3P (base16 @OZ) "00fe"
@@ -264,7 +301,7 @@ -- Left "Step 2. False Boolean Check(op) | {61694 < 400}"
 --
 type BaseN (opts :: OptT) (n :: Nat) = BaseN' opts n 'True
-type BaseN' (opts :: OptT) (n :: Nat) p = '( opts, ReadBase Int n Id, p, ShowBase n Id, String)
+type BaseN' (opts :: OptT) (n :: Nat) p = '(opts, ReadBase Int n Id, p, ShowBase n Id, String)
 
 base16 :: Proxy (BaseN opts 16)
 base16 = basen
@@ -319,7 +356,7 @@ between :: Proxy (BetweenN opts m n)
 between = mkProxy3
 
-type BetweenN (opts :: OptT) m n = '( opts, Id, Between m n Id, Id, Int)
+type BetweenN (opts :: OptT) m n = '(opts, Id, Between m n Id, Id, Int)
 type BetweenR (opts :: OptT) m n = RefinedEmulate opts (Between m n Id) Int
 
 type LuhnR (opts :: OptT) (n :: Nat) = MakeR3 (LuhnT opts n)
@@ -334,7 +371,7 @@ --
 -- | uses builtin 'Luhn'
 type LuhnT (opts :: OptT) (n :: Nat) =
-   '( opts
+   '(opts
     , Map (ReadP Int Id) (Ones Id)
     , Msg "incorrect number of digits:"
           (Len == n) && Luhn Id
@@ -388,7 +425,7 @@ -- Left "Step 2. False Boolean Check(op) | FalseP"
 --
 -- >>> newRefined3P (Proxy @(ReadShow' OL Rational (Msg (PrintF "invalid=%3.2f" (FromRational Double Id)) (Id > (15 % 1))))) "13 % 3"
--- Left "Step 2. False Boolean Check(op) | {invalid=4.3313 % 3 > 15 % 1}"
+-- Left "Step 2. False Boolean Check(op) | {invalid=4.33 13 % 3 > 15 % 1}"
 --
 -- >>> newRefined3P (Proxy @(ReadShow' OZ Rational (Id > (11 % 1)))) "13 % 3"
 -- Left "Step 2. False Boolean Check(op) | FalseP"
@@ -403,10 +440,10 @@ -- >>> newRefined3P (readshow @OZ @Value) "Number 123.4"
 -- Right (Refined3 {r3In = Number 123.4, r3Out = "Number 123.4"})
 --
-type ReadShow (opts :: OptT) (t :: Type) = '( opts, ReadP t Id, 'True, ShowP Id, String)
+type ReadShow (opts :: OptT) (t :: Type) = '(opts, ReadP t Id, 'True, ShowP Id, String)
 type ReadShowR (opts :: OptT) (t :: Type) = MakeR3 (ReadShow opts t)
 
-type ReadShow' (opts :: OptT) (t :: Type) p = '( opts, ReadP t Id, p, ShowP Id, String)
+type ReadShow' (opts :: OptT) (t :: Type) p = '(opts, ReadP t Id, p, ShowP Id, String)
 type ReadShowR' (opts :: OptT) (t :: Type) p = MakeR3 (ReadShow' opts t p)
 
 readshow :: Proxy (ReadShow opts t)
src/Predicate/Prelude.hs view
@@ -1,11112 +1,52 @@ {-# OPTIONS -Wall #-}
-{-# OPTIONS -Wno-compat #-}
-{-# OPTIONS -Wincomplete-record-updates #-}
-{-# OPTIONS -Wincomplete-uni-patterns #-}
-{-# OPTIONS -Wredundant-constraints #-}
-{-# LANGUAGE TypeOperators #-}
-{-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE AllowAmbiguousTypes #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeApplications #-}
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE PolyKinds #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE TupleSections #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# LANGUAGE NoOverloadedLists #-}
-{-# LANGUAGE NoStarIsType #-}
-{- |
-     Dsl for evaluating and displaying type level expressions
-
-     Contains instances of the class 'P' for evaluating expressions at the type level.
--}
-module Predicate.Prelude (
-
-  -- ** boolean expressions
-    type (&&)
-  , type (&&~)
-  , type (||)
-  , type (||~)
-  , type (~>)
-  , Not
-  , Ands
-  , Ors
-  , Asc
-  , Asc'
-  , Desc
-  , Desc'
-  , Between
-  , BetweenA
-  , type (<..>)
-  , All
-  , Any
-  , AllPositive
-  , Positive
-  , AllNegative
-  , Negative
-  , AndA
-  , type (&*)
-  , OrA
-  , type (|+)
-  , IdBool
-
-  -- ** regex expressions
-  , Re
-  , Re'
-  , Rescan
-  , Rescan'
-  , RescanRanges
-  , RescanRanges'
-  , Resplit
-  , Resplit'
-  , ReplaceAll
-  , ReplaceAll'
-  , ReplaceOne
-  , ReplaceOne'
-  , ReplaceAllString
-  , ReplaceAllString'
-  , ReplaceOneString
-  , ReplaceOneString'
-  , ReplaceFn
-  , ReplaceFn1
-  , ReplaceFn2
-  , ReplaceFn3
-
-  -- ** tuple expressions
-  , Fst
-  , Snd
-  , Thd
-  , L1
-  , L2
-  , L3
-  , L4
-  , L5
-  , L6
-  , Dup
-  , Swap
-  , SwapC(..)
-  , Assoc
-  , Unassoc
-  , Pairs
-
- -- ** character predicates
-  , IsLower
-  , IsUpper
-  , IsDigit
-  , IsSpace
-  , IsPunctuation
-  , IsControl
-  , IsHexDigit
-  , IsOctDigit
-  , IsSeparator
-  , IsLatin1
-
-  , IsLowerAll
-  , IsUpperAll
-  , IsDigitAll
-  , IsSpaceAll
-  , IsPunctuationAll
-  , IsControlAll
-  , IsHexDigitAll
-  , IsOctDigitAll
-  , IsSeparatorAll
-  , IsLatin1All
-
-  -- ** datetime expressions
-  , FormatTimeP
-  , ParseTimeP
-  , ParseTimeP'
-  , ParseTimes
-  , ParseTimes'
-  , MkDay
-  , MkDay'
-  , UnMkDay
-  , MkDayExtra
-  , MkDayExtra'
-  , ToWeekDate
-  , ToWeekYear
-  , ToDay
-  , ToTime
-  , MkTime
-  , MkTime'
-  , UnMkTime
-  , PosixToUTCTime
-  , UTCTimeToPosix
-
-  -- ** numeric expressions
-  , type (+)
-  , type (-)
-  , type (*)
-  , type (/)
-  , Negate
-  , Abs
-  , Signum
-  , FromInteger
-  , FromInteger'
-  , FromIntegral
-  , FromIntegral'
-  , Truncate
-  , Truncate'
-  , Ceiling
-  , Ceiling'
-  , Floor
-  , Floor'
-  , Even
-  , Odd
-  , Div
-  , Mod
-  , DivMod
-  , QuotRem
-  , Quot
-  , Rem
-  , LogBase
-  , type (^)
-  , type (**)
-
-  -- *** rational numbers
-  , type (%)
-  , type (-%)
-  , ToRational
-  , FromRational
-  , FromRational'
-
- -- ** proxy expressions
-  , MkProxy
-  , ProxyT
-  , ProxyT'
-  , Unproxy
-
- -- ** read / show expressions
-  , ShowP
-  , ReadP
-  , ReadP'
-  , ReadQ
-  , ReadQ'
-  , ReadMaybe
-  , ReadMaybe'
-  , ReadBase
-  , ReadBase'
-  , ShowBase
-
-  -- ** aeson expressions
-  , ParseJson'
-  , ParseJson
-  , EncodeJson
-  , EncodeJsonFile
-  , ParseJsonFile'
-  , ParseJsonFile
-
-  -- ** arrow expressions
-  , type (&&&)
-  , type (***)
-  , First
-  , Second
-  , type (|||)
-  , type (+++)
-
- -- ** compare expressions
-  , type (>)
-  , type (>=)
-  , type (==)
-  , type (/=)
-  , type (<=)
-  , type (<)
-  , type (>~)
-  , type (>=~)
-  , type (==~)
-  , type (/=~)
-  , type (<=~)
-  , type (<~)
-  , Gt
-  , Ge
-  , Same
-  , Le
-  , Lt
-  , Ne
-  , type (==!)
-  , OrdP
-  , OrdA'
-  , OrdA
-  , OrdI
-  , type (===~)
-  , Cmp
-  , CmpI
-
-  -- ** enum expressions
-  , Succ
-  , Pred
-  , FromEnum
-  , ToEnum
-  , ToEnum'
-  , EnumFromTo
-  , type (...)
-  , EnumFromThenTo
-  -- *** bounded enum expressions
-  , SuccB
-  , SuccB'
-  , PredB
-  , PredB'
-  , ToEnumBDef
-  , ToEnumBDef'
-  , ToEnumBFail
-
- -- ** wrap / unwrap expressions
-  , Unwrap
-  , Wrap
-  , Wrap'
-  , Coerce
-  , Coerce2
-
-  -- ** list / foldable expressions
-  , Map
-  , Concat
-  , ConcatMap
-  , Partition
-  , PartitionBy
-  , GroupBy
-  , Filter
-  , Break
-  , Span
-  , Intercalate
-  , Elem
-  , Inits
-  , Tails
-  , Ones
-  , OneP
-  , Len
-  , Length
-  , PadL
-  , PadR
-  , Cycle
-  , SplitAts
-  , SplitAt
-  , ChunksOf
-  , Rotate
-  , Take
-  , Drop
-  , Min
-  , Max
-  , Sum
-  , Product
-  , IsEmpty
-  , Null
-  , Null'
-  , ToList
-  , ToList'
-  , IToList
-  , IToList'
-  , FromList
-  , ToNEList
-  , EmptyList
-  , EmptyList'
-  , Singleton
-  , Reverse
-  , ReverseL
-  , SortBy
-  , SortOn
-  , SortOnDesc
-  , Remove
-  , Keep
- -- *** overloaded list expressions
-  , ToListExt
-  , FromListExt
-
- -- ** maybe expressions
-  , MkNothing
-  , MkNothing'
-  , MkJust
-  , IsNothing
-  , IsJust
-  , MapMaybe
-  , CatMaybes
-  , Just
-  , JustDef
-  , JustFail
-  , MaybeIn
-  , MaybeBool
-
- -- ** either expressions
-  , PartitionEithers
-  , IsLeft
-  , IsRight
-  , MkLeft
-  , MkLeft'
-  , MkRight
-  , MkRight'
-  , Left'
-  , Right'
-  , LeftDef
-  , LeftFail
-  , RightDef
-  , RightFail
-  , EitherBool
-  , EitherIn
-
-  -- ** semigroup / monoid expressions
-  , type (<>)
-  , MConcat
-  , SConcat
-  , STimes
-  , SapA
-  , SapA'
-  , MEmptyT
-  , MEmptyT'
-  , MEmptyP
-  , MEmpty2
-  , MEmpty2'
-
-  -- ** indexing expressions
-  , Ix
-  , Ix'
-  , IxL
-  , type (!!)
-  , type (!!?)
-  , Lookup
-  , LookupDef
-  , LookupDef'
-  , LookupFail
-  , LookupFail'
-
- -- ** cons / uncons expressions
-  , type (:+)
-  , type (+:)
-  , type (++)
-  , Uncons
-  , Unsnoc
-  , Head
-  , Tail
-  , Init
-  , Last
-  , HeadDef
-  , HeadFail
-  , TailDef
-  , TailFail
-  , LastDef
-  , LastFail
-  , InitDef
-  , InitFail
-
- -- ** these expressions
-  , PartitionThese
-  , Thiss
-  , Thats
-  , Theses
-  , This'
-  , That'
-  , These'
-  , IsThis
-  , IsThat
-  , IsThese
-  , MkThis
-  , MkThis'
-  , MkThat
-  , MkThat'
-  , MkThese
-  , ThisDef
-  , ThisFail
-  , ThatDef
-  , ThatFail
-  , TheseDef
-  , TheseFail
-  , TheseIn
-  , TheseId
-  , TheseX
-
- -- ** fold / unfold expressions
-  , Scanl
-  , ScanN
-  , ScanNA
-  , FoldN
-  , FoldL
-  , Unfoldr
-  , IterateN
-  , IterateUntil
-  , IterateWhile
-  , IterateNWhile
-  , IterateNUntil
-
-  -- ** failure expressions
-  , Fail
-  , Failp
-  , Failt
-  , FailS
-  , Catch
-  , Catch'
-
-  -- ** zip expressions
-  , ZipThese
-  , ZipL
-  , ZipR
-  , Zip
-  , Unzip
-  , Unzip3
-
-  -- ** conditional expressions
-  , If
-  , Case
-  , Case'
-  , Case''
-  , Guards
-  , GuardsQuick
-  , Guard
-  , ExitWhen
-  , GuardSimple
-  , GuardsN
-  , GuardsDetail
-
-  , Bools
-  , BoolsQuick
-  , BoolsN
-
-  -- ** IO expressions
-  , ReadFile
-  , FileExists
-  , ReadDir
-  , DirExists
-  , ReadEnv
-  , ReadEnvAll
-  , TimeUtc
-  , TimeZt
-  , AppendFile
-  , WriteFile
-  , WriteFile'
-  , Stdout
-  , Stderr
-  , Stdin
-  , ReadIO
-  , ReadIO'
-
-  -- ** string expressions
-  , ToLower
-  , ToUpper
-  , ToTitle
-  , TrimBoth
-  , TrimL
-  , TrimR
-  , StripR
-  , StripL
-  , IsPrefix
-  , IsInfix
-  , IsSuffix
-  , IsPrefixI
-  , IsInfixI
-  , IsSuffixI
-  , ToString
-  , FromString
-  , FromString'
-
-  -- ** print expressions
-  , PrintF
-  , PrintL
-  , PrintT
-
-  -- ** higher order expressions
-  , Pure
-  , Pure2
-  , FoldMap
-  , type (<$)
-  , type (<*)
-  , type (*>)
-  , FMapFst
-  , FMapSnd
-  , Sequence
-  , Traverse
-  , Join
-  , EmptyT
-  , type (<|>)
-  , Extract
-  , Duplicate
-
-  -- ** expression combinators
-  , type ($)
-  , type (&)
-  , Do
-  , Dot
-  , RDot
-  , type (>>)
-  , type (<<)
-  , type (>>>)
-  , DoN
-  , type ($$)
-  , type ($&)
-  , K
-  , Hole
-  , Skip
-  , type (|>)
-  , type (>|)
-  , type (>|>)
-  , Uncurry
-
-  -- *** parallel expressions
-  , Para
-  , ParaN
-  , Repeat
-
-  -- ** miscellaneous
-  , Both
-  , Prime
-  , PrimeNext
-  , Luhn
-  , Char1
-
-  -- ** tuples
-  , Tuple2
-  , Tuple3
-  , Tuple4
-  , Tuple5
-  , Tuple6
- ) where
-import Predicate.Core
-import Predicate.Util
-import Safe (succMay, predMay, toEnumMay)
-import GHC.TypeLits (Symbol,Nat,KnownSymbol,KnownNat,ErrorMessage((:$$:),(:<>:)))
-import qualified GHC.TypeLits as GL
-import Control.Lens hiding (iall)
-import Data.List
-import qualified Data.Text.Lens as DTL
-import Data.Proxy
-import Control.Applicative
-import Data.Typeable
-import Control.Monad.Except
-import qualified Control.Exception as E
-import Data.Kind (Type)
-import qualified Text.Regex.PCRE.Heavy as RH
-import Data.String
-import Data.Foldable
-import Data.Maybe
-import Control.Arrow
-import qualified Data.Semigroup as SG
-import qualified Data.List.NonEmpty as N
-import Data.List.NonEmpty (NonEmpty(..))
-import qualified Numeric
-import Data.Char
-import Data.Function
-import Data.These (These(..))
-import Data.Ratio
-import Data.Time
-import Data.Coerce
-import Data.Void
-import qualified Data.Sequence as Seq
-import Text.Printf
-import System.Directory
-import Control.Comonad
-import System.IO
-import System.Environment
-import qualified GHC.Exts as GE
-import Data.Bool
-import Data.Either
-import qualified Data.Type.Equality as DE
-import Data.Time.Calendar.WeekDate
-import qualified Data.Time.Clock.System as CP
-import qualified Data.Time.Clock.POSIX as P
-import qualified Data.Aeson as A
-import qualified Data.ByteString.Char8 as BS8
-import qualified Data.ByteString.Lazy.Char8 as BL8
-import qualified Data.Text as T
-import qualified Data.Text.Lazy as TL
-import qualified Data.Map.Strict as M
-
--- $setup
--- >>> :set -XDataKinds
--- >>> :set -XTypeApplications
--- >>> :set -XTypeOperators
--- >>> :set -XOverloadedStrings
--- >>> :set -XNoOverloadedLists
--- >>> import qualified Data.Map.Strict as M
--- >>> import qualified Data.Text as T
--- >>> import Safe (readNote)
-
--- | a type level predicate for a monotonic increasing list
---
--- >>> pl @Asc "aaacdef"
--- True (All(6))
--- TrueT
---
--- >>> pz @Asc [1,2,3,4,5,5,7]
--- TrueT
---
--- >>> pz @Asc' [1,2,3,4,5,5,7]
--- FalseT
---
--- >>> pz @Asc "axacdef"
--- FalseT
---
-
-
--- | a type level predicate for a monotonic increasing list
-data Asc
-type AscT = All (Fst Id <= Snd Id) Pairs
-
-instance P AscT x => P Asc x where
-  type PP Asc x = PP AscT x
-  eval _ = evalBool (Proxy @AscT)
-
--- | a type level predicate for a strictly increasing list
-data Asc'
-type AscT' = All (Fst Id < Snd Id) Pairs
-
-instance P AscT' x => P Asc' x where
-  type PP Asc' x = PP AscT' x
-  eval _ = evalBool (Proxy @AscT')
-
--- | a type level predicate for a monotonic decreasing list
-data Desc
-type DescT = All (Fst Id >= Snd Id) Pairs
-
-instance P DescT x => P Desc x where
-  type PP Desc x = PP DescT x
-  eval _ = evalBool (Proxy @DescT)
--- | a type level predicate for a strictly decreasing list
-data Desc'
-type DescT' = All (Fst Id > Snd Id) Pairs
-
-instance P DescT' x => P Desc' x where
-  type PP Desc' x = PP DescT' x
-  eval _ = evalBool (Proxy @DescT')
-
-
---type AscAlt = SortOn Id Id == Id
---type DescAlt = SortOnDesc Id Id == Id
-
--- | A predicate that determines if the value is between \'p\' and \'q\'
---
--- >>> pz @(Between 5 8 Len) [1,2,3,4,5,5,7]
--- TrueT
---
--- >>> pz @(5 <..> 8) 6
--- TrueT
---
--- >>> pl @(Between 5 8 Id) 9
--- False (9 <= 8)
--- FalseT
---
--- >>> pz @(10 % 4 <..> 40 % 5) 4
--- TrueT
---
--- >>> pz @(10 % 4 <..> 40 % 5) 33
--- FalseT
---
-data Between p q r -- reify as it is used a lot! nicer specific messages at the top level!
-
-instance (Ord (PP p x)
-       , Show (PP p x)
-       , PP r x ~ PP p x
-       , PP r x ~ PP q x
-       , P p x
-       , P q x
-       , P r x
-       ) => P (Between p q r) x where
-  type PP (Between p q r) x = Bool
-  eval _ opts x = do
-    let msg0 = "Between"
-    rr <- eval (Proxy @r) opts x
-    case getValueLR opts msg0 rr [] of
-      Left e -> pure e
-      Right r -> do
-        lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x [hh rr]
-        pure $ case lr of
-          Left e -> e
-          Right (p,q,pp,qq) ->
-            let hhs = [hh rr, hh pp, hh qq]
-            in if p <= r && r <= q then mkNodeB opts True (showL opts p <> " <= " <> showL opts r <> " <= " <> showL opts q) hhs
-               else if p > r then mkNodeB opts False (showL opts p <> " <= " <> showL opts r) hhs
-               else mkNodeB opts False (showL opts r <> " <= " <> showL opts q) hhs
-
-
-data p <..> q
-infix 4 <..>
-
-type BetweenT p q = Between p q Id
-
-instance P (BetweenT p q) x => P (p <..> q) x where
-  type PP (p <..> q) x = PP (BetweenT p q) x
-  eval _ = evalBool (Proxy @(BetweenT p q))
-
--- | between for tuples
---
--- >>> pl @(BetweenA (Fst Id) (Snd Id)) ((1,4),8)
--- False (8 <= 4)
--- FalseT
---
--- >>> pl @(BetweenA (Fst Id) (Snd Id)) ((1,4),0)
--- False (1 <= 0)
--- FalseT
---
--- >>> pl @(BetweenA (Fst Id) (Snd Id)) ((1,4),3)
--- True (1 <= 3 <= 4)
--- TrueT
---
--- >>> pl @(BetweenA (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2018-10-12"
--- True (2017-04-11 <= 2018-10-12 <= 2018-12-30)
--- TrueT
---
--- >>> pl @(BetweenA (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2019-10-12"
--- False (2019-10-12 <= 2018-12-30)
--- FalseT
---
--- >>> pl @(BetweenA (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2016-10-12"
--- False (2017-04-11 <= 2016-10-12)
--- FalseT
---
-
-{- too much data mitigated somewhat by Hide
-type BetweenAT p q = '(p,q) >> Between (Fst (Fst Id)) (Snd (Fst Id)) (Snd Id)
-
-instance P (BetweenAT p q) x => P (BetweenA p q) x where
-  type PP (BetweenA p q) x = PP (BetweenAT p q) x
-  eval _ = evalBool (Proxy @(BetweenAT p q))
--}
-data BetweenA p q
-
-instance (PP p x ~ (a,a')
-       , P q x
-       , PP q x ~ a
-       , Ord a
-       , a ~ a'
-       , Show a
-       , P p x
-       ) => P (BetweenA p q) x where
-  type PP (BetweenA p q) x = Bool
-  eval _ opts x = do
-    let msg0 = "BetweenA"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right ((p1,p2),q,pp,qq) ->
-        [hh pp, hh qq] & if p1 <= q && q <= p2 then mkNodeB opts True (showL opts p1 <> " <= " <> showL opts q <> " <= " <> showL opts p2)
-        else if p1 > q then mkNodeB opts False (showL opts p1 <> " <= " <> showL opts q)
-        else mkNodeB opts False (showL opts q <> " <= " <> showL opts p2)
-
--- | similar to 'all'
---
--- >>> pl @(All (Between 1 8 Id) Id) [7,3,4,1,2,9,0,1]
--- False (All(8) i=5 (9 <= 8))
--- FalseT
---
--- >>> pz @(All Odd Id) [1,5,11,5,3]
--- TrueT
---
--- >>> pz @(All Odd Id) []
--- TrueT
---
--- >>> run @'OANV @(All Even Id) [1,5,11,5,3]
--- False All(5) i=0 (1 == 0)
--- |
--- +- P Id [1,5,11,5,3]
--- |
--- +- False i=0:1 == 0
--- |  |
--- |  +- P 1 `mod` 2 = 1
--- |  |  |
--- |  |  +- P I
--- |  |  |
--- |  |  `- P '2
--- |  |
--- |  `- P '0
--- |
--- +- False i=1:1 == 0
--- |  |
--- |  +- P 5 `mod` 2 = 1
--- |  |  |
--- |  |  +- P I
--- |  |  |
--- |  |  `- P '2
--- |  |
--- |  `- P '0
--- |
--- +- False i=2:1 == 0
--- |  |
--- |  +- P 11 `mod` 2 = 1
--- |  |  |
--- |  |  +- P I
--- |  |  |
--- |  |  `- P '2
--- |  |
--- |  `- P '0
--- |
--- +- False i=3:1 == 0
--- |  |
--- |  +- P 5 `mod` 2 = 1
--- |  |  |
--- |  |  +- P I
--- |  |  |
--- |  |  `- P '2
--- |  |
--- |  `- P '0
--- |
--- `- False i=4:1 == 0
---    |
---    +- P 3 `mod` 2 = 1
---    |  |
---    |  +- P I
---    |  |
---    |  `- P '2
---    |
---    `- P '0
--- FalseT
---
-data All p q
-
-instance (P p a
-        , PP p a ~ Bool
-        , PP q x ~ f a
-        , P q x
-        , Show a
-        , Foldable f
-        ) => P (All p q) x where
-  type PP (All p q) x = Bool
-  eval _ opts x = do
-    let msg0 = "All"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-            ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide (Proxy @p) opts a) [0::Int ..] (toList q)
-            pure $ case splitAndAlign opts msg0 ts of
-                 Left e -> e
-                 Right abcs ->
-                   let hhs = hh qq : map (hh . fixit) ts
-                       msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
-                   in case find (not . view _1) abcs of
-                        Nothing -> mkNodeB opts True msg1 hhs
-                        Just (_,(i,_),tt) ->
-                          mkNodeB opts False (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
-
-showIndex :: (Show i, Num i) => i -> String
-showIndex i = show (i+0)
--- | similar to 'any'
---
--- >>> pl @(Any Even Id) [1,5,11,5,3]
--- False (Any(5))
--- FalseT
---
--- >>> pl @(Any Even Id) [1,5,112,5,3]
--- True (Any(5) i=2 (0 == 0))
--- TrueT
---
--- >>> pz @(Any Even Id) []
--- FalseT
---
-data Any p q
-
-instance (P p a
-        , PP p a ~ Bool
-        , PP q x ~ f a
-        , P q x
-        , Show a
-        , Foldable f
-        ) => P (Any p q) x where
-  type PP (Any p q) x = Bool
-  eval _ opts x = do
-    let msg0 = "Any"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-            ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide (Proxy @p) opts a) [0::Int ..] (toList q)
-            pure $ case splitAndAlign opts msg0 ts of
-                 Left e -> e
-                 Right abcs ->
-                   let hhs = hh qq : map (hh . fixit) ts
-                       msg1 = msg0 ++ "(" ++ show (length q) ++ ")"
-                   in case find (view _1) abcs of
-                        Nothing -> mkNodeB opts False msg1 hhs
-                        Just (_,(i,_),tt) ->
-                          mkNodeB opts True (msg1 <> " i=" ++ showIndex i ++ " " <> topMessage tt) hhs
-
-
--- | a type level predicate for all positive elements in a list
---
--- >>> pz @AllPositive [1,5,10,2,3]
--- TrueT
---
--- >>> pz @AllPositive [0,1,5,10,2,3]
--- FalseT
---
--- >>> pz @AllPositive [3,1,-5,10,2,3]
--- FalseT
---
--- >>> pz @AllNegative [-1,-5,-10,-2,-3]
--- TrueT
---
-data AllPositive
-type AllPositiveT = All Positive Id
-
-instance P AllPositiveT x => P AllPositive x where
-  type PP AllPositive x = PP AllPositiveT x
-  eval _ = evalBool (Proxy @AllPositiveT)
-
--- | a type level predicate for all negative elements in a list
-data AllNegative
-type AllNegativeT = All Negative Id
-
-instance P AllNegativeT x => P AllNegative x where
-  type PP AllNegative x = PP AllNegativeT x
-  eval _ = evalBool (Proxy @AllNegativeT)
-
-
-type Positive = Gt 0
-
-type Negative = Lt 0
-
--- | 'unzip' equivalent
---
--- >>> pz @Unzip (zip [1..5] "abcd")
--- PresentT ([1,2,3,4],"abcd")
---
-data Unzip
-type UnzipT = '(Map (Fst Id) Id, Map (Snd Id) Id)
-
-instance P UnzipT x => P Unzip x where
-  type PP Unzip x = PP UnzipT x
-  eval _ = eval (Proxy @UnzipT)
-
-
--- | 'unzip3' equivalent
---
--- >>> pz @Unzip3 (zip3 [1..5] "abcd" (cycle [True,False]))
--- PresentT ([1,2,3,4],"abcd",[True,False,True,False])
---
-data Unzip3
-type Unzip3T = '(Map (Fst Id) Id, Map (Snd Id) Id, Map (Thd Id) Id)
-
-instance P Unzip3T x => P Unzip3 x where
-  type PP Unzip3 x = PP Unzip3T x
-  eval _ = eval (Proxy @Unzip3T)
-
-
--- | represents a predicate using a 'Symbol' as a regular expression
--- evaluates 'Re' and returns True if there is a match
---
--- >>> pz @(Re "^\\d{2}:\\d{2}:\\d{2}$" Id) "13:05:25"
--- TrueT
---
-data Re' (rs :: [ROpt]) p q
-data Re p q
-
-instance (GetROpts rs
-        , PP p x ~ String
-        , PP q x ~ String
-        , P p x
-        , P q x
-        ) => P (Re' rs p q) x where
-  type PP (Re' rs p q) x = Bool
-  eval _ opts x = do
-    let msg0 = "Re" <> unlessNull rs ("' " <> displayROpts fs)
-        (fs,rs) = getROpts @rs
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case compileRegex @rs opts msg1 p hhs of
-            Left tta -> tta
-            Right regex ->
-               let b = q RH.=~ regex
-               in mkNodeB opts b (msg1 <> litVerbose opts " | " q) hhs
-
-type ReT p q = Re' '[] p q
-
-instance P (ReT p q) x => P (Re p q) x where
-  type PP (Re p q) x = PP (ReT p q) x
-  eval _ = evalBool (Proxy @(ReT p q))
-
--- only way with rescan is to be explicit: no repeats! and useanchors but not (?m)
--- or just use Re' but then we only get a bool ie doesnt capture groups
--- rescan returns Right [] as an failure!
--- [] is failure!
-
-
--- | runs a regex matcher returning the original values and optionally any groups
---
--- >>> pz @(Rescan "^(\\d{2}):(\\d{2}):(\\d{2})$" Id) "13:05:25"
--- PresentT [("13:05:25",["13","05","25"])]
---
--- >>> pz @(Rescan (Snd Id) "13:05:25") ('a',"^(\\d{2}):(\\d{2}):(\\d{2})$")
--- PresentT [("13:05:25",["13","05","25"])]
---
--- >>> pz @(Rescan "^(\\d{2}):(\\d{2}):(\\d{2})$" Id >> Snd (Head Id) >> Map (ReadP Int Id) Id) "13:05:25"
--- PresentT [13,5,25]
---
--- >>> pl @(Rescan "(\\d+)\\D?" Id >> Map (Second (ReadP Int (OneP Id))) Id) "123-444-987"
--- Present [("123-",123),("444-",444),("987",987)] ((>>) [("123-",123),("444-",444),("987",987)] | {Map [("123-",123),("444-",444),("987",987)] | [("123-",["123"]),("444-",["444"]),("987",["987"])]})
--- PresentT [("123-",123),("444-",444),("987",987)]
---
-data Rescan' (rs :: [ROpt]) p q
-
-instance (GetROpts rs
-        , PP p x ~ String
-        , PP q x ~ String
-        , P p x
-        , P q x
-        ) => P (Rescan' rs p q) x where
-  type PP (Rescan' rs p q) x = [(String, [String])]
-  eval _ opts x = do
-    let msg0 = "Rescan" <> unlessNull rs ("' " <> displayROpts fs)
-        (fs,rs) = getROpts @rs
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case compileRegex @rs opts msg1 p hhs of
-          Left tta -> tta
-          Right regex ->
-            case splitAt (oRecursion opts) $ RH.scan regex q of
-              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
-              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
-                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) [hh pp, hh qq]
-              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) [hh pp, hh qq]
-
-data Rescan p q
-type RescanT p q = Rescan' '[] p q
-
-instance P (RescanT p q) x => P (Rescan p q) x where
-  type PP (Rescan p q) x = PP (RescanT p q) x
-  eval _ = eval (Proxy @(RescanT p q))
-
-
--- | similar to 'Rescan' but gives the column start and ending positions instead of values
---
--- >>> pz @(RescanRanges "^(\\d{2}):(\\d{2}):(\\d{2})$" Id) "13:05:25"
--- PresentT [((0,8),[(0,2),(3,5),(6,8)])]
---
-data RescanRanges' (rs :: [ROpt]) p q
-
-instance (GetROpts rs
-        , PP p x ~ String
-        , PP q x ~ String
-        , P p x
-        , P q x
-        ) => P (RescanRanges' rs p q) x where
-  type PP (RescanRanges' rs p q) x = [((Int,Int), [(Int,Int)])]
-  eval _ opts x = do
-    let msg0 = "RescanRanges" <> unlessNull rs ("' " <> displayROpts fs)
-        (fs,rs) = getROpts @rs
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case compileRegex @rs opts msg1 p hhs of
-          Left tta -> tta
-          Right regex ->
-            case splitAt (oRecursion opts) $ RH.scanRanges regex q of
-              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
-              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
-                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) hhs
-              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) hhs
-
-data RescanRanges p q
-type RescanRangesT p q = RescanRanges' '[] p q
-
-instance P (RescanRangesT p q) x => P (RescanRanges p q) x where
-  type PP (RescanRanges p q) x = PP (RescanRangesT p q) x
-  eval _ = eval (Proxy @(RescanRangesT p q))
-
--- | splits a string on a regex delimiter
---
--- >>> pz @(Resplit "\\." Id) "141.201.1.22"
--- PresentT ["141","201","1","22"]
---
--- >>> pz @(Resplit (Singleton (Fst Id)) (Snd Id)) (':', "12:13:1")
--- PresentT ["12","13","1"]
---
--- >>> pl @(Resplit' '[ 'Caseless ] "aBc" Id) "123AbC456abc"
--- Present ["123","456",""] (Resplit' ['Caseless] (aBc) ["123","456",""] | 123AbC456abc)
--- PresentT ["123","456",""]
---
-data Resplit' (rs :: [ROpt]) p q
-
-instance (GetROpts rs
-        , PP p x ~ String
-        , PP q x ~ String
-        , P p x
-        , P q x
-        ) => P (Resplit' rs p q) x where
-  type PP (Resplit' rs p q) x = [String]
-  eval _ opts x = do
-    let msg0 = "Resplit" <> unlessNull rs ("' " <> displayROpts fs)
-        (fs,rs) = getROpts @rs
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case compileRegex @rs opts msg1 p hhs of
-          Left tta -> tta
-          Right regex ->
-            case splitAt (oRecursion opts) $ RH.split regex q of
-              (b, _:_) -> mkNode opts (FailT ("Regex looping(" ++ show (oRecursion opts) ++ ")")) (msg1 <> " " <> show (take 10 b) <> "..." <> showVerbose opts " | " q) hhs
-              ([], _) -> -- this is a failure cos empty string returned: so reuse p?
-                         mkNode opts (FailT "Regex no results") (msg1 <> showVerbose opts " | " q) hhs
-              (b, _) -> mkNode opts (PresentT b) (lit01 opts msg1 b "" q) hhs
-
-data Resplit p q
-type ResplitT p q = Resplit' '[] p q
-
-instance P (ResplitT p q) x => P (Resplit p q) x where
-  type PP (Resplit p q) x = PP (ResplitT p q) x
-  eval _ = eval (Proxy @(ResplitT p q))
-
--- | replaces regex \'s\' with a string \'s1\' inside the value
---
--- >>> pz @(ReplaceAllString 'ROverWrite "\\." ":" Id) "141.201.1.22"
--- PresentT "141:201:1:22"
---
-data ReplaceImpl (alle :: Bool) (rs :: [ROpt]) p q r
-
-instance (GetBool b
-        , GetROpts rs
-        , PP p x ~ String
-        , PP q x ~ RReplace
-        , PP r x ~ String
-        , P p x
-        , P q x
-        , P r x
-        ) => P (ReplaceImpl b rs p q r) x where
-  type PP (ReplaceImpl b rs p q r) x = String
-  eval _ opts x = do
-    let msg0 = "Replace" <> (if alle then "All" else "One") <> unlessNull rs ("' " <> displayROpts fs)
-        (fs,rs) = getROpts @rs
-        alle = getBool @b
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case compileRegex @rs opts msg1 p hhs of
-          Left tta -> pure tta
-          Right regex -> do
-            rr <- eval (Proxy @r) opts x
-            pure $ case getValueLR opts msg0 rr hhs of
-              Left e -> e
-              Right r ->
-               let ret :: String
-                   ret = case q of
-                           RReplace o s ->
-                             let g fn = (if alle then RH.gsub else RH.sub) regex fn r
-                             in g (case o of
-                                  RPrepend -> (s <>)
-                                  ROverWrite -> const s
-                                  RAppend -> (<> s))
-                           RReplace1 s -> (if alle then RH.gsub else RH.sub) regex s r
-                           RReplace2 s -> (if alle then RH.gsub else RH.sub) regex s r
-                           RReplace3 s -> (if alle then RH.gsub else RH.sub) regex s r
-               in mkNode opts (PresentT ret) (msg1 <> " " <> litL opts r <> litVerbose opts " | " ret) (hhs <> [hh rr])
-
-data ReplaceAll' (rs :: [ROpt]) p q r
-type ReplaceAllT' (rs :: [ROpt]) p q r = ReplaceImpl 'True rs p q r
-
-instance P (ReplaceAllT' rs p q r) x => P (ReplaceAll' rs p q r) x where
-  type PP (ReplaceAll' rs p q r) x = PP (ReplaceAllT' rs p q r) x
-  eval _ = eval (Proxy @(ReplaceAllT' rs p q r))
-
-data ReplaceAll p q r
-type ReplaceAllT p q r = ReplaceAll' '[] p q r
-
-instance P (ReplaceAllT p q r) x => P (ReplaceAll p q r) x where
-  type PP (ReplaceAll p q r) x = PP (ReplaceAllT p q r) x
-  eval _ = eval (Proxy @(ReplaceAllT p q r))
-
-data ReplaceOne' (rs :: [ROpt]) p q r
-type ReplaceOneT' (rs :: [ROpt]) p q r = ReplaceImpl 'False rs p q r
-
-instance P (ReplaceOneT' rs p q r) x => P (ReplaceOne' rs p q r) x where
-  type PP (ReplaceOne' rs p q r) x = PP (ReplaceOneT' rs p q r) x
-  eval _ = eval (Proxy @(ReplaceOneT' rs p q r))
-
--- | replace first occurrence of string \'p\' with '\q'\ in \'r\'
---
--- >>> pl @(ReplaceOneString 'ROverWrite "abc" "def" Id) "123abc456abc"
--- Present "123def456abc" (ReplaceOne (abc) 123abc456abc | 123def456abc)
--- PresentT "123def456abc"
---
--- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1530144000123+0530)"
--- PresentT 2018-06-28 05:30:00.123 +0530
---
--- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1593460089052+0800)"
--- PresentT 2020-06-30 03:48:09.052 +0800
---
--- >>> pz @(Rescan "^Date\\((\\d+)(\\d{3}[+-]\\d{4})\\)" Id >> Head Id >> Snd Id >> (Id !! 0 <> "." <> Id !! 1)  >> ParseTimeP ZonedTime "%s%Q%z" Id) "Date(1593460089052+0800)"
--- PresentT 2020-06-30 03:48:09.052 +0800
---
-data ReplaceOne p q r
-type ReplaceOneT p q r = ReplaceOne' '[] p q r
-
-instance P (ReplaceOneT p q r) x => P (ReplaceOne p q r) x where
-  type PP (ReplaceOne p q r) x = PP (ReplaceOneT p q r) x
-  eval _ = eval (Proxy @(ReplaceOneT p q r))
-
--- | replace all occurrences of string \'p\' with '\q'\ in \'r\'
---
--- >>> pl @(ReplaceAllString 'ROverWrite "abc" "def" Id) "123abc456abc"
--- Present "123def456def" (ReplaceAll (abc) 123abc456abc | 123def456def)
--- PresentT "123def456def"
---
--- >>> pl @(ReplaceAllString' '[] 'ROverWrite "abc" "def" Id) "123AbC456abc"
--- Present "123AbC456def" (ReplaceAll (abc) 123AbC456abc | 123AbC456def)
--- PresentT "123AbC456def"
---
--- >>> pl @(ReplaceAllString' '[ 'Caseless ] 'ROverWrite "abc" "def" Id) "123AbC456abc"
--- Present "123def456def" (ReplaceAll' ['Caseless] (abc) 123AbC456abc | 123def456def)
--- PresentT "123def456def"
---
--- >>> pl @(ReplaceAllString 'RPrepend "abc" "def" Id) "123AbC456abc"
--- Present "123AbC456defabc" (ReplaceAll (abc) 123AbC456abc | 123AbC456defabc)
--- PresentT "123AbC456defabc"
---
--- >>> pl @(ReplaceAllString 'ROverWrite "abc" "def" Id) "123AbC456abc"
--- Present "123AbC456def" (ReplaceAll (abc) 123AbC456abc | 123AbC456def)
--- PresentT "123AbC456def"
---
--- >>> pl @(ReplaceAllString 'RAppend "abc" "def" Id) "123AbC456abc"
--- Present "123AbC456abcdef" (ReplaceAll (abc) 123AbC456abc | 123AbC456abcdef)
--- PresentT "123AbC456abcdef"
---
-data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
-type ReplaceAllStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceAll' rs p (ReplaceFn o q) r
-
-instance P (ReplaceAllStringT' rs o p q r) x => P (ReplaceAllString' rs o p q r) x where
-  type PP (ReplaceAllString' rs o p q r) x = PP (ReplaceAllStringT' rs o p q r) x
-  eval _ = eval (Proxy @(ReplaceAllStringT' rs o p q r))
-
-data ReplaceAllString o p q r
-type ReplaceAllStringT o p q r = ReplaceAllString' '[] o p q r
-
-instance P (ReplaceAllStringT o p q r) x => P (ReplaceAllString o p q r) x where
-  type PP (ReplaceAllString o p q r) x = PP (ReplaceAllStringT o p q r) x
-  eval _ = eval (Proxy @(ReplaceAllStringT o p q r))
-
-data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r
-type ReplaceOneStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceOne' rs p (ReplaceFn o q) r
-
-instance P (ReplaceOneStringT' rs o p q r) x => P (ReplaceOneString' rs o p q r) x where
-  type PP (ReplaceOneString' rs o p q r) x = PP (ReplaceOneStringT' rs o p q r) x
-  eval _ = eval (Proxy @(ReplaceOneStringT' rs o p q r))
-
-data ReplaceOneString (o :: ReplaceFnSub) p q r
-type ReplaceOneStringT (o :: ReplaceFnSub) p q r = ReplaceOneString' '[] o p q r
-
-instance P (ReplaceOneStringT o p q r) x => P (ReplaceOneString o p q r) x where
-  type PP (ReplaceOneString o p q r) x = PP (ReplaceOneStringT o p q r) x
-  eval _ = eval (Proxy @(ReplaceOneStringT o p q r))
-
--- | Simple replacement string: see 'ReplaceAllString' and 'ReplaceOneString'
---
-data ReplaceFn (o :: ReplaceFnSub) p
-
-instance (GetReplaceFnSub r
-        , PP p x ~ String
-        , P p x) => P (ReplaceFn r p) x where
-  type PP (ReplaceFn r p) x = RReplace
-  eval _ opts x = do
-    let msg0 = "ReplaceFn"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = RReplace (getReplaceFnSub @r) p
-        in mkNode opts (PresentT b) (msg0 <> showVerbose opts " | " p) [hh pp]
-
--- | A replacement function @(String -> [String] -> String)@ which returns the whole match and the groups
--- Used by 'RH.sub' and 'RH.gsub'
---
--- Requires "Text.Show.Functions"
---
-data ReplaceFn1 p
-
-instance (PP p x ~ (String -> [String] -> String)
-        , P p x) => P (ReplaceFn1 p) x where
-  type PP (ReplaceFn1 p) x = RReplace
-  eval _ opts x = do
-    let msg0 = "ReplaceFn1 (String -> [String] -> String)"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right f -> mkNode opts (PresentT (RReplace1 f)) msg0 [hh pp]
-
--- | A replacement function @(String -> String)@ that yields the whole match
--- Used by 'RH.sub' and 'RH.gsub'
---
--- Requires "Text.Show.Functions"
---
--- >>> :m + Text.Show.Functions
--- >>> pz @(ReplaceAll "\\." (ReplaceFn2 (Fst Id)) (Snd Id)) (\x -> x <> ":" <> x, "141.201.1.22")
--- PresentT "141.:.201.:.1.:.22"
---
-data ReplaceFn2 p
-
-instance (PP p x ~ (String -> String)
-        , P p x) => P (ReplaceFn2 p) x where
-  type PP (ReplaceFn2 p) x = RReplace
-  eval _ opts x = do
-    let msg0 = "ReplaceFn2 (String -> String)"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right f -> mkNode opts (PresentT (RReplace2 f)) msg0 [hh pp]
-
--- | A replacement function @([String] -> String)@ which yields the groups
--- Used by 'RH.sub' and 'RH.gsub'
---
--- Requires "Text.Show.Functions"
---
--- >>> :m + Text.Show.Functions
--- >>> pz @(ReplaceAll "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" (ReplaceFn3 (Fst Id)) (Snd Id)) (\ys -> intercalate  " | " $ map (show . succ . readNote @Int "invalid int") ys, "141.201.1.22")
--- PresentT "142 | 202 | 2 | 23"
---
-data ReplaceFn3 p
-
-instance (PP p x ~ ([String] -> String)
-        , P p x) => P (ReplaceFn3 p) x where
-  type PP (ReplaceFn3 p) x = RReplace
-  eval _ opts x = do
-    let msg0 = "ReplaceFn3 ([String] -> String)"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right f -> mkNode opts (PresentT (RReplace3 f)) msg0 [hh pp]
-
-
--- | a predicate for determining if a string 'Data.Text.IsText' belongs to the given character set
---
--- >>> pz @IsSpace '\t'
--- TrueT
---
--- >>> pz @IsSpace ' '
--- TrueT
---
--- >>> pz @IsSpace 'x'
--- FalseT
---
--- >>> pz @IsLower 'a'
--- TrueT
---
--- >>> pz @IsLower 'X'
--- FalseT
---
--- >>> pz @IsHexDigit 'A'
--- TrueT
---
--- >>> pz @IsHexDigit 'g'
--- FalseT
---
-data IsCharSet (cs :: CharSet)
-
-instance ( x ~ Char
-         , GetCharSet cs
-         ) => P (IsCharSet cs) x where
-  type PP (IsCharSet cs) x = Bool
-  eval _ opts c =
-    let msg0 = "Is" ++ drop 1 (show cs)
-        (cs,f) = getCharSet @cs
-        b = f c
-    in pure $ mkNodeB opts b (msg0 <> showVerbose opts " | " [c]) []
-
--- | predicate for determining if a character is lowercase
---
--- >>> pz @IsLower '1'
--- FalseT
---
--- >>> pz @IsLower 'a'
--- TrueT
---
--- >>> pz @(Map '(IsControl, IsLatin1, IsHexDigit, IsOctDigit, IsDigit, IsPunctuation, IsSeparator, IsSpace) Id) "abc134"
--- PresentT [(False,True,True,False,False,False,False,False),(False,True,True,False,False,False,False,False),(False,True,True,False,False,False,False,False),(False,True,True,True,True,False,False,False),(False,True,True,True,True,False,False,False),(False,True,True,True,True,False,False,False)]
---
-data IsLower
-type IsLowerT = IsCharSet 'CLower
-
-instance P IsLowerT x => P IsLower x where
-  type PP IsLower x = PP IsLowerT x
-  eval _ = evalBool (Proxy @IsLowerT)
-
-data IsUpper
-type IsUpperT = IsCharSet 'CUpper
-
-instance P IsUpperT x => P IsUpper x where
-  type PP IsUpper x = PP IsUpperT x
-  eval _ = evalBool (Proxy @IsUpperT)
-
--- | predicate for determining if the character is a digit
---
--- >>> pz @IsDigit 'g'
--- FalseT
---
--- >>> pz @IsDigit '9'
--- TrueT
---
-data IsDigit
-type IsDigitT = IsCharSet 'CNumber
-instance P IsDigitT x => P IsDigit x where
-  type PP IsDigit x = Bool
-  eval _ = evalBool (Proxy @IsDigitT)
-
-data IsSpace
-type IsSpaceT = IsCharSet 'CSpace
-instance P IsSpaceT x => P IsSpace x where
-  type PP IsSpace x = Bool
-  eval _ = evalBool (Proxy @IsSpaceT)
-
-data IsPunctuation
-type IsPunctuationT = IsCharSet 'CPunctuation
-instance P IsPunctuationT x => P IsPunctuation x where
-  type PP IsPunctuation x = Bool
-  eval _ = evalBool (Proxy @IsPunctuationT)
-
-data IsControl
-type IsControlT = IsCharSet 'CControl
-instance P IsControlT x => P IsControl x where
-  type PP IsControl x = Bool
-  eval _ = evalBool (Proxy @IsControlT)
-
-data IsHexDigit
-type IsHexDigitT = IsCharSet 'CHexDigit
-instance P IsHexDigitT x => P IsHexDigit x where
-  type PP IsHexDigit x = Bool
-  eval _ = evalBool (Proxy @IsHexDigitT)
-
-data IsOctDigit
-type IsOctDigitT = IsCharSet 'COctDigit
-instance P IsOctDigitT x => P IsOctDigit x where
-  type PP IsOctDigit x = Bool
-  eval _ = evalBool (Proxy @IsOctDigitT)
-
-data IsSeparator
-type IsSeparatorT = IsCharSet 'CSeparator
-instance P IsSeparatorT x => P IsSeparator x where
-  type PP IsSeparator x = Bool
-  eval _ = evalBool (Proxy @IsSeparatorT)
-
-data IsLatin1
-type IsLatin1T = IsCharSet 'CLatin1
-instance P IsLatin1T x => P IsLatin1 x where
-  type PP IsLatin1 x = Bool
-  eval _ = evalBool (Proxy @IsLatin1T)
-
-
-
--- | a predicate for determining if a string 'Data.Text.IsText' belongs to the given character set
---
--- >>> pz @IsLowerAll "abc"
--- TrueT
---
--- >>> pz @IsLowerAll "abcX"
--- FalseT
---
--- >>> pz @IsLowerAll (T.pack "abcX")
--- FalseT
---
--- >>> pz @IsHexDigitAll "01efA"
--- TrueT
---
--- >>> pz @IsHexDigitAll "01egfA"
--- FalseT
---
--- | predicate for determining if a string is all lowercase
---
--- >>> pz @IsLowerAll "abcdef213"
--- FalseT
---
--- >>> pz @IsLowerAll "abcdef"
--- TrueT
---
--- >>> pz @IsLowerAll ""
--- TrueT
---
--- >>> pz @IsLowerAll "abcdefG"
--- FalseT
---
--- >>> pl @(Just Uncons >> IsUpper &* IsLowerAll) "AbcdE"
--- False ((>>) False | {True (&*) False | (IsLowerAll | "bcdE")})
--- FalseT
---
--- >>> pl @(Just Uncons >> IsUpper &* IsLowerAll) "Abcde"
--- True ((>>) True | {True (&*) True})
--- TrueT
---
--- >>> pl @(Just Uncons >> IsUpper &* IsLowerAll) "xbcde"
--- False ((>>) False | {False (&*) True | (IsUpper | "x")})
--- FalseT
---
--- >>> pl @(Just Uncons >> IsUpper &* IsLowerAll) "X"
--- True ((>>) True | {True (&*) True})
--- TrueT
---
--- >>> pz @( '(IsControlAll, IsLatin1All , IsHexDigitAll , IsOctDigitAll , IsDigitAll , IsPunctuationAll , IsSeparatorAll , IsSpaceAll ) ) "abc134"
--- PresentT (False,True,True,False,False,False,False,False)
---
--- >>> pl @(SplitAts [1,2,10] Id >> Para '[IsLowerAll, IsDigitAll, IsUpperAll ]) "abdefghi"
--- Present [True,False,False] ((>>) [True,False,False] | {Para(0) [True,False,False] | ["a","bd","efghi"]})
--- PresentT [True,False,False]
---
--- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll ]) "a98efghi"
--- False ((>>) False | {Bool(2) [] (IsUpperAll | "efghi")})
--- FalseT
---
--- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll || IsLowerAll ]) "a98efghi"
--- True ((>>) True | {Bools})
--- TrueT
---
--- >>> pl @(SplitAts [1,2,10] Id >> BoolsQuick "" '[IsLowerAll, IsDigitAll, IsUpperAll || IsLowerAll ]) "a98efgHi"
--- False ((>>) False | {Bool(2) [] (False || False | (IsUpperAll | "efgHi") || (IsLowerAll | "efgHi"))})
--- FalseT
---
-data IsCharSetAll (cs :: CharSet)
-
-instance (GetCharSet cs
-        , Show a
-        , DTL.IsText a
-        ) => P (IsCharSetAll cs) a where
-  type PP (IsCharSetAll cs) a = Bool
-  eval _ opts as =
-    let b = allOf DTL.text f as
-        msg0 = "Is" ++ drop 1 (show cs) ++ "All"
-        (cs,f) = getCharSet @cs
-    in pure $ mkNodeB opts b (msg0 <> showVerbose opts " | " as) []
-
-data CharSet = CLower
-             | CUpper
-             | CNumber
-             | CSpace
-             | CPunctuation
-             | CControl
-             | CHexDigit
-             | COctDigit
-             | CSeparator
-             | CLatin1
-             deriving Show
-
-class GetCharSet (cs :: CharSet) where
-  getCharSet :: (CharSet, Char -> Bool)
-instance GetCharSet 'CLower where
-  getCharSet = (CLower, isLower)
-instance GetCharSet 'CUpper where
-  getCharSet = (CUpper, isUpper)
-instance GetCharSet 'CNumber where
-  getCharSet = (CNumber, isNumber)
-instance GetCharSet 'CSpace where
-  getCharSet = (CSpace, isSpace)
-instance GetCharSet 'CPunctuation where
-  getCharSet = (CPunctuation, isPunctuation)
-instance GetCharSet 'CControl where
-  getCharSet = (CControl, isControl)
-instance GetCharSet 'CHexDigit where
-  getCharSet = (CHexDigit, isHexDigit)
-instance GetCharSet 'COctDigit where
-  getCharSet = (COctDigit, isOctDigit)
-instance GetCharSet 'CSeparator where
-  getCharSet = (CSeparator, isSeparator)
-instance GetCharSet 'CLatin1 where
-  getCharSet = (CLatin1, isLatin1)
-
-data IsLowerAll
-type IsLowerAllT = IsCharSetAll 'CLower
-
-instance P IsLowerAllT x => P IsLowerAll x where
-  type PP IsLowerAll x = PP IsLowerAllT x
-  eval _ = evalBool (Proxy @IsLowerAllT)
-
-data IsUpperAll
-type IsUpperAllT = IsCharSetAll 'CUpper
-
-instance P IsUpperAllT x => P IsUpperAll x where
-  type PP IsUpperAll x = PP IsUpperAllT x
-  eval _ = evalBool (Proxy @IsUpperAllT)
-
--- | predicate for determining if the string is all digits
---
--- >>> pz @IsDigitAll "213G"
--- FalseT
---
--- >>> pz @IsDigitAll "929"
--- TrueT
---
-data IsDigitAll
-type IsDigitAllT = IsCharSetAll 'CNumber
-instance P IsDigitAllT x => P IsDigitAll x where
-  type PP IsDigitAll x = Bool
-  eval _ = evalBool (Proxy @IsDigitAllT)
-
--- | predicate for determining if the string is all spaces
---
--- >>> pz @IsSpaceAll "213G"
--- FalseT
---
--- >>> pz @IsSpaceAll "    "
--- TrueT
---
--- >>> pz @IsSpaceAll ""
--- TrueT
---
-data IsSpaceAll
-type IsSpaceAllT = IsCharSetAll 'CSpace
-instance P IsSpaceAllT x => P IsSpaceAll x where
-  type PP IsSpaceAll x = Bool
-  eval _ = evalBool (Proxy @IsSpaceAllT)
-
-data IsPunctuationAll
-type IsPunctuationAllT = IsCharSetAll 'CPunctuation
-instance P IsPunctuationAllT x => P IsPunctuationAll x where
-  type PP IsPunctuationAll x = Bool
-  eval _ = evalBool (Proxy @IsPunctuationAllT)
-
-data IsControlAll
-type IsControlAllT = IsCharSetAll 'CControl
-instance P IsControlAllT x => P IsControlAll x where
-  type PP IsControlAll x = Bool
-  eval _ = evalBool (Proxy @IsControlAllT)
-
-data IsHexDigitAll
-type IsHexDigitAllT = IsCharSetAll 'CHexDigit
-instance P IsHexDigitAllT x => P IsHexDigitAll x where
-  type PP IsHexDigitAll x = Bool
-  eval _ = evalBool (Proxy @IsHexDigitAllT)
-
-data IsOctDigitAll
-type IsOctDigitAllT = IsCharSetAll 'COctDigit
-instance P IsOctDigitAllT x => P IsOctDigitAll x where
-  type PP IsOctDigitAll x = Bool
-  eval _ = evalBool (Proxy @IsOctDigitAllT)
-
-data IsSeparatorAll
-type IsSeparatorAllT = IsCharSetAll 'CSeparator
-instance P IsSeparatorAllT x => P IsSeparatorAll x where
-  type PP IsSeparatorAll x = Bool
-  eval _ = evalBool (Proxy @IsSeparatorAllT)
-
-data IsLatin1All
-type IsLatin1AllT = IsCharSetAll 'CLatin1
-instance P IsLatin1AllT x => P IsLatin1All x where
-  type PP IsLatin1All x = Bool
-  eval _ = evalBool (Proxy @IsLatin1AllT)
-
-
--- | converts a string 'Data.Text.Lens.IsText' value to lower case
---
--- >>> pz @ToLower "HeLlO wOrld!"
--- PresentT "hello world!"
---
-data ToLower
-
-instance ( Show a
-         , DTL.IsText a
-         ) => P ToLower a where
-  type PP ToLower a = a
-  eval _ opts as =
-    let msg0 = "ToLower"
-        xs = as & DTL.text %~ toLower
-    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
-
--- | converts a string 'Data.Text.Lens.IsText' value to upper case
---
--- >>> pz @ToUpper "HeLlO wOrld!"
--- PresentT "HELLO WORLD!"
---
-data ToUpper
-
-instance ( Show a
-         , DTL.IsText a
-         ) => P ToUpper a where
-  type PP ToUpper a = a
-  eval _ opts as =
-    let msg0 = "ToUpper"
-        xs = as & DTL.text %~ toUpper
-    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
-
-
--- | converts a string 'Data.Text.Lens.IsText' value to title case
---
--- >>> pz @ToTitle "HeLlO wOrld!"
--- PresentT "Hello world!"
---
--- >>> data Color = Red | White | Blue | Green | Black deriving (Show,Eq,Enum,Bounded,Read)
--- >>> pz @(ToTitle >> ReadP Color Id) "red"
--- PresentT Red
---
-data ToTitle
-
-instance ( Show a
-         , DTL.IsText a
-         ) => P ToTitle a where
-  type PP ToTitle a = a
-  eval _ opts as =
-    let msg0 = "ToTitle"
-        xs = toTitleAll (as ^. DTL.unpacked) ^. DTL.packed
-    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
-
-
-toTitleAll :: String -> String
-toTitleAll (x:xs) = toUpper x : map toLower xs
-toTitleAll [] = []
-
-
--- | similar to 'Data.List.inits'
---
--- >>> pz @Inits [4,8,3,9]
--- PresentT [[],[4],[4,8],[4,8,3],[4,8,3,9]]
---
--- >>> pz @Inits []
--- PresentT [[]]
---
-data Inits
-
-instance ( [a] ~ x
-         , Show a
-         ) => P Inits x where
-  type PP Inits x = [x]
-  eval _ opts as =
-    let msg0 = "Inits"
-        xs = inits as
-    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
-
--- | similar to 'Data.List.tails'
---
--- >>> pz @Tails [4,8,3,9]
--- PresentT [[4,8,3,9],[8,3,9],[3,9],[9],[]]
---
--- >>> pz @Tails []
--- PresentT [[]]
---
-data Tails
-
-instance ( [a] ~ x
-         , Show a
-         ) => P Tails x where
-  type PP Tails x = [x]
-  eval _ opts as =
-    let msg0 = "Tails"
-        xs = tails as
-    in pure $ mkNode opts (PresentT xs) (show01 opts msg0 xs as) []
-
--- | split a list into single values
---
--- >>> pz @(Ones Id) [4,8,3,9]
--- PresentT [[4],[8],[3],[9]]
---
--- >>> pz @(Ones Id) []
--- PresentT []
---
-data Ones p
-
-instance ( PP p x ~ [a]
-         , P p x
-         , Show a
-         ) => P (Ones p) x where
-  type PP (Ones p) x = [PP p x]
-  eval _ opts x = do
-    let msg0 = "Ones"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case chkSize opts msg0 p [hh pp] of
-          Left e -> e
-          Right () ->
-            let d = map pure p
-            in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
--- | similar to 'show'
---
--- >>> pz @(ShowP Id) [4,8,3,9]
--- PresentT "[4,8,3,9]"
---
--- >>> pz @(ShowP Id) 'x'
--- PresentT "'x'"
---
--- >>> pz @(ShowP (42 -% 10)) 'x'
--- PresentT "(-21) % 5"
---
-data ShowP p
-
-instance ( Show (PP p x)
-         , P p x
-         ) => P (ShowP p) x where
-  type PP (ShowP p) x = String
-  eval _ opts x = do
-    let msg0 = "ShowP"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = show p
-        in mkNode opts (PresentT d) (msg0 <> " " <> litL opts d <> showVerbose opts " | " p) [hh pp]
-
--- | type level expression representing a formatted time
--- similar to 'Data.Time.formatTime' using a type level 'Symbol' to get the formatting string
---
--- >>> pz @(FormatTimeP "%F %T" Id) (readNote @LocalTime "invalid localtime" "2019-05-24 05:19:59")
--- PresentT "2019-05-24 05:19:59"
---
--- >>> pz @(FormatTimeP (Fst Id) (Snd Id)) ("the date is %d/%m/%Y", readNote @Day "invalid day" "2019-05-24")
--- PresentT "the date is 24/05/2019"
---
-data FormatTimeP p q
-
-instance (PP p x ~ String
-        , FormatTime (PP q x)
-        , P p x
-        , Show (PP q x)
-        , P q x
-        ) => P (FormatTimeP p q) x where
-  type PP (FormatTimeP p q) x = String
-  eval _ opts x = do
-    let msg0 = "FormatTimeP"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            b = formatTime defaultTimeLocale p q
-        in mkNode opts (PresentT b) (msg1 <> " " <> litL opts b <> showVerbose opts " | " q) [hh pp, hh qq]
-
--- | similar to 'Data.Time.parseTimeM' where \'t\' is the 'Data.Time.ParseTime' type, \'p\' is the datetime format and \'q\' points to the content to parse
---
--- >>> pz @(ParseTimeP LocalTime "%F %T" Id) "2019-05-24 05:19:59"
--- PresentT 2019-05-24 05:19:59
---
--- >>> pz @(ParseTimeP LocalTime "%F %T" "2019-05-24 05:19:59") (Right "never used")
--- PresentT 2019-05-24 05:19:59
---
--- keeping \'q\' as we might want to extract from a tuple
-data ParseTimeP' t p q
-
-instance (ParseTime (PP t a)
-        , Typeable (PP t a)
-        , Show (PP t a)
-        , P p a
-        , P q a
-        , PP p a ~ String
-        , PP q a ~ String
-        ) => P (ParseTimeP' t p q) a where
-  type PP (ParseTimeP' t p q) a = PP t a
-  eval _ opts a = do
-    let msg0 = "ParseTimeP " <> t
-        t = showT @(PP t a)
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> " (" <> p <> ")"
-            hhs = [hh pp, hh qq]
-        in case parseTimeM @Maybe @(PP t a) True defaultTimeLocale p q of
-             Just b -> mkNode opts (PresentT b) (lit01 opts msg1 b "fmt=" p <> showVerbose opts " | " q) hhs
-             Nothing -> mkNode opts (FailT (msg1 <> " failed to parse")) "" hhs
-
-data ParseTimeP (t :: Type) p q
-type ParseTimePT (t :: Type) p q = ParseTimeP' (Hole t) p q
-
-instance P (ParseTimePT t p q) x => P (ParseTimeP t p q) x where
-  type PP (ParseTimeP t p q) x = PP (ParseTimePT t p q) x
-  eval _ = eval (Proxy @(ParseTimePT t p q))
-
--- | A convenience method to match against many different datetime formats to find a match
---
--- >>> pz @(ParseTimes LocalTime '["%Y-%m-%d %H:%M:%S", "%m/%d/%y %H:%M:%S", "%B %d %Y %H:%M:%S", "%Y-%m-%dT%H:%M:%S"] "03/11/19 01:22:33") ()
--- PresentT 2019-03-11 01:22:33
---
--- >>> pz @(ParseTimes LocalTime (Fst Id) (Snd Id)) (["%Y-%m-%d %H:%M:%S", "%m/%d/%y %H:%M:%S", "%B %d %Y %H:%M:%S", "%Y-%m-%dT%H:%M:%S"], "03/11/19 01:22:33")
--- PresentT 2019-03-11 01:22:33
---
-data ParseTimes' t p q
-
-instance (ParseTime (PP t a)
-        , Typeable (PP t a)
-        , Show (PP t a)
-        , P p a
-        , P q a
-        , PP p a ~ [String]
-        , PP q a ~ String
-        ) => P (ParseTimes' t p q) a where
-  type PP (ParseTimes' t p q) a = PP t a
-  eval _ opts a = do
-    let msg0 = "ParseTimes " <> t
-        t = showT @(PP t a)
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-            zs = map (\d -> (d,) <$> parseTimeM @Maybe @(PP t a) True defaultTimeLocale d q) p
-        in case catMaybes zs of
-             [] -> mkNode opts (FailT ("no match on (" ++ q ++ ")")) msg0 hhs
-             (d,b):_ -> mkNode opts (PresentT b) (lit01 opts msg0 b "fmt=" d <> showVerbose opts " | " q) hhs
-
-data ParseTimes (t :: Type) p q
-type ParseTimesT (t :: Type) p q = ParseTimes' (Hole t) p q
-
-instance P (ParseTimesT t p q) x => P (ParseTimes t p q) x where
-  type PP (ParseTimes t p q) x = PP (ParseTimesT t p q) x
-  eval _ = eval (Proxy @(ParseTimesT t p q))
-
--- | create a 'Day' from three int values passed in as year month and day
---
--- >>> pz @(MkDay '(1,2,3) >> Just Id) ()
--- PresentT 0001-02-03
---
--- >>> pz @(Just (MkDay '(1,2,3))) 1
--- PresentT 0001-02-03
---
--- >>> pz @(MkDay Id) (2019,12,30)
--- PresentT (Just 2019-12-30)
---
--- >>> pz @(MkDay' (Fst Id) (Snd Id) (Thd Id)) (2019,99,99999)
--- PresentT Nothing
---
--- >>> pz @(MkDay Id) (1999,3,13)
--- PresentT (Just 1999-03-13)
---
-data MkDay' p q r
-
-instance (P p x
-        , P q x
-        , P r x
-        , PP p x ~ Int
-        , PP q x ~ Int
-        , PP r x ~ Int
-        ) => P (MkDay' p q r) x where
-  type PP (MkDay' p q r) x = Maybe Day
-  eval _ opts x = do
-    let msg0 = "MkDay"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        rr <- eval (Proxy @r) opts x
-        pure $ case getValueLR opts msg0 rr hhs of
-          Left e -> e
-          Right r ->
-            let mday = fromGregorianValid (fromIntegral p) q r
-            in mkNode opts (PresentT mday) (show01' opts msg0 mday "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
-
-data MkDay p
-type MkDayT p = MkDay' (Fst p) (Snd p) (Thd p)
-
-instance P (MkDayT p) x => P (MkDay p) x where
-  type PP (MkDay p) x = PP (MkDayT p) x
-  eval _ = eval (Proxy @(MkDayT p))
-
--- | uncreate a 'Day' returning year month and day
---
--- >>> pz @(UnMkDay Id) (readNote "invalid day" "2019-12-30")
--- PresentT (2019,12,30)
---
-data UnMkDay p
-
-instance ( PP p x ~ Day
-         , P p x
-         ) => P (UnMkDay p) x where
-  type PP (UnMkDay p) x = (Int, Int, Int)
-  eval _ opts x = do
-    let msg0 = "UnMkDay"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (fromIntegral -> y, m, d) = toGregorian p
-            b = (y, m, d)
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-
--- | create a 'Day' + Week + Day of Week from three int values passed in as year month and day
---
--- >>> pz @(MkDayExtra '(1,2,3) >> Just Id >> Fst Id) ()
--- PresentT 0001-02-03
---
--- >>> pz @(Fst (Just (MkDayExtra '(1,2,3)))) 1
--- PresentT 0001-02-03
---
--- >>> pz @(MkDayExtra Id) (2019,12,30)
--- PresentT (Just (2019-12-30,1,1))
---
--- >>> pz @(MkDayExtra' (Fst Id) (Snd Id) (Thd Id)) (2019,99,99999)
--- PresentT Nothing
---
--- >>> pz @(MkDayExtra Id) (1999,3,13)
--- PresentT (Just (1999-03-13,10,6))
---
-data MkDayExtra' p q r
-
-instance (P p x
-        , P q x
-        , P r x
-        , PP p x ~ Int
-        , PP q x ~ Int
-        , PP r x ~ Int
-        ) => P (MkDayExtra' p q r) x where
-  type PP (MkDayExtra' p q r) x = Maybe (Day, Int, Int)
-  eval _ opts x = do
-    let msg0 = "MkDayExtra"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        rr <- eval (Proxy @r) opts x
-        pure $ case getValueLR opts msg0 rr hhs of
-          Left e -> e
-          Right r ->
-            let mday = fromGregorianValid (fromIntegral p) q r
-                b = mday <&> \day ->
-                      let (_, week, dow) = toWeekDate day
-                      in (day, week, dow)
-            in mkNode opts (PresentT b) (show01' opts msg0 b "(y,m,d)=" (p,q,r)) (hhs <> [hh rr])
-
-data MkDayExtra p
-type MkDayExtraT p = MkDayExtra' (Fst p) (Snd p) (Thd p)
-
-instance P (MkDayExtraT p) x => P (MkDayExtra p) x where
-  type PP (MkDayExtra p) x = PP (MkDayExtraT p) x
-  eval _ = eval (Proxy @(MkDayExtraT p))
-
--- | get day of week
---
--- >>> pz @(Just (MkDay '(2020,7,11)) >> '(UnMkDay Id, ToWeekYear Id,ToWeekDate Id)) ()
--- PresentT ((2020,7,11),28,(6,"Saturday"))
---
-data ToWeekDate p
-
-instance ( P p x
-         , PP p x ~ Day
-         ) => P (ToWeekDate p) x where
-  type PP (ToWeekDate p) x = (Int, String)
-  eval _ opts x = do
-    let msg0 = "ToWeekDate"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (_, _week, dow) = toWeekDate p
-            dowString =
-              case dow of
-                 1 -> "Monday"
-                 2 -> "Tuesday"
-                 3 -> "Wednesday"
-                 4 -> "Thursday"
-                 5 -> "Friday"
-                 6 -> "Saturday"
-                 7 -> "Sunday"
-                 _ -> error $ "oops: ToWeekDate invalid " ++ show dow
-        in mkNode opts (PresentT (dow,dowString)) (show01 opts msg0 dow p) [hh pp]
-
--- | get week number of the year
---
--- >>> pz @(Just (MkDay '(2020,7,11)) >> ToWeekYear Id) ()
--- PresentT 28
---
-data ToWeekYear p
-
-instance ( P p x
-         , PP p x ~ Day
-         ) => P (ToWeekYear p) x where
-  type PP (ToWeekYear p) x = Int
-  eval _ opts x = do
-    let msg0 = "ToWeekYear"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (_, week, _dow) = toWeekDate p
-        in mkNode opts (PresentT week) (show01 opts msg0 week p) [hh pp]
-
-class ToDayC a where
-  getDay :: a -> Day
-instance ToDayC UTCTime where
-  getDay = utctDay
-instance ToDayC ZonedTime where
-  getDay = getDay . zonedTimeToLocalTime
-instance ToDayC LocalTime where
-  getDay = localDay
-instance ToDayC Day where
-  getDay = id
-instance ToDayC Rational where
-  getDay = getDay . P.posixSecondsToUTCTime . fromRational
-instance ToDayC CP.SystemTime where
-  getDay = getDay . CP.systemToUTCTime
-
-class ToTimeC a where
-  getTime :: a -> TimeOfDay
-instance ToTimeC UTCTime where
-  getTime = getTime . utctDayTime
-instance ToTimeC ZonedTime where
-  getTime = getTime . zonedTimeToLocalTime
-instance ToTimeC LocalTime where
-  getTime = localTimeOfDay
-instance ToTimeC TimeOfDay where
-  getTime = id
-instance ToTimeC DiffTime where
-  getTime = timeToTimeOfDay
-instance ToTimeC Rational where
-  getTime = getTime . P.posixSecondsToUTCTime . fromRational
-instance ToTimeC CP.SystemTime where
-  getTime = getTime . CP.systemToUTCTime
-
--- | extract 'Day' from a DateTime
---
--- >>> pz @(ReadP UTCTime Id >> ToDay Id) "2020-07-06 12:11:13Z"
--- PresentT 2020-07-06
---
-data ToDay p
-
-instance ( P p x
-         , Show (PP p x)
-         , ToDayC (PP p x)
-         ) => P (ToDay p) x where
-  type PP (ToDay p) x = Day
-  eval _ opts x = do
-    let msg0 = "ToDay"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let ret = getDay p
-        in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
-
--- | extract 'TimeOfDay' from DateTime
---
--- >>> pz @(ReadP UTCTime Id >> ToDay Id) "2020-07-06 12:11:13Z"
--- PresentT 2020-07-06
---
-data ToTime p
-
-instance ( P p x
-         , Show (PP p x)
-         , ToTimeC (PP p x)
-         ) => P (ToTime p) x where
-  type PP (ToTime p) x = TimeOfDay
-  eval _ opts x = do
-    let msg0 = "ToTime"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let ret = getTime p
-        in mkNode opts (PresentT ret) (show01 opts msg0 ret p) [hh pp]
-
-
--- | create a 'TimeOfDay' from three int values passed in as year month and day
---
--- >>> pz @(MkTime' (Fst Id) (Snd Id) (Thd Id)) (13,99,99999)
--- PresentT 13:99:99999
---
-data MkTime' p q r
-
-instance (P p x
-        , P q x
-        , P r x
-        , PP p x ~ Int
-        , PP q x ~ Int
-        , PP r x ~ Rational
-        ) => P (MkTime' p q r) x where
-  type PP (MkTime' p q r) x = TimeOfDay
-  eval _ opts x = do
-    let msg0 = "MkTime"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        rr <- eval (Proxy @r) opts x
-        pure $ case getValueLR opts msg0 rr hhs of
-          Left e -> e
-          Right r ->
-            let mtime = TimeOfDay p q (fromRational r)
-            in mkNode opts (PresentT mtime) (show01' opts msg0 mtime "(h,m,s)=" (p,q,r)) (hhs <> [hh rr])
-
--- | create a 'TimeOfDay' from a three-tuple of year month and day
---
--- >>> pz @(MkTime '(1,2,3 % 12345)) ()
--- PresentT 01:02:00.000243013365
---
--- >>> pz @(MkTime Id) (12,13,65)
--- PresentT 12:13:65
---
--- >>> pz @(MkTime Id) (17,3,13)
--- PresentT 17:03:13
---
-data MkTime p
-type MkTimeT p = MkTime' (Fst p) (Snd p) (Thd p)
-
-instance P (MkTimeT p) x => P (MkTime p) x where
-  type PP (MkTime p) x = PP (MkTimeT p) x
-  eval _ = eval (Proxy @(MkTimeT p))
-
-
--- | uncreate a 'TimeOfDay' returning hour minute seconds picoseconds
---
--- >>> pz @(ReadP UTCTime "2019-01-01 12:13:14.1234Z" >> ToTime Id >> UnMkTime Id) ()
--- PresentT (12,13,70617 % 5000)
---
--- >>> pz @(ReadP UTCTime Id >> ToTime Id >> UnMkTime Id) "2020-07-22 08:01:14.127Z"
--- PresentT (8,1,14127 % 1000)
---
--- >>> pz @(ReadP ZonedTime Id >> '(UnMkDay (ToDay Id), UnMkTime (ToTime Id))) "2020-07-11 11:41:12.333 CET"
--- PresentT ((2020,7,11),(11,41,12333 % 1000))
---
-data UnMkTime p
-
-instance ( PP p x ~ TimeOfDay
-         , P p x
-         ) => P (UnMkTime p) x where
-  type PP (UnMkTime p) x = (Int, Int, Rational)
-  eval _ opts x = do
-    let msg0 = "UnMkTime"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let TimeOfDay h m s = p
-            b = (h, m, toRational s)
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-
--- microsoft json date is x*1000 ie milliseconds
-
--- | convert posix time (seconds since 01-01-1970) to 'UTCTime'
---
--- >>> pl @(PosixToUTCTime Id) 1593384312
--- Present 2020-06-28 22:45:12 UTC (PosixToUTCTime 2020-06-28 22:45:12 UTC | 1593384312 % 1)
--- PresentT 2020-06-28 22:45:12 UTC
---
--- >>> pl @(PosixToUTCTime Id >> UTCTimeToPosix Id) 1593384312
--- Present 1593384312 % 1 ((>>) 1593384312 % 1 | {UTCTimeToPosix 1593384312 % 1 | 2020-06-28 22:45:12 UTC})
--- PresentT (1593384312 % 1)
---
--- >>> pl @(PosixToUTCTime (Id % 1000)) 1593384312000
--- Present 2020-06-28 22:45:12 UTC (PosixToUTCTime 2020-06-28 22:45:12 UTC | 1593384312 % 1)
--- PresentT 2020-06-28 22:45:12 UTC
---
--- >>> pl @(PosixToUTCTime Id) (3600*4+60*7+12)
--- Present 1970-01-01 04:07:12 UTC (PosixToUTCTime 1970-01-01 04:07:12 UTC | 14832 % 1)
--- PresentT 1970-01-01 04:07:12 UTC
---
--- >>> pz @(Rescan "^Date\\((\\d+)([^\\)]+)\\)" Id >> Head Id >> Snd Id >> ReadP Integer (Id !! 0) >> PosixToUTCTime (Id % 1000)) "Date(1530144000000+0530)"
--- PresentT 2018-06-28 00:00:00 UTC
---
-data PosixToUTCTime p
-
-instance ( PP p x ~ Rational
-         , P p x
-         ) => P (PosixToUTCTime p) x where
-  type PP (PosixToUTCTime p) x = UTCTime
-  eval _ opts x = do
-    let msg0 = "PosixToUTCTime"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = P.posixSecondsToUTCTime (fromRational p)
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
--- | convert 'UTCTime' to posix time (seconds since 01-01-1970)
---
--- >>> pl @(ReadP UTCTime Id >> UTCTimeToPosix Id) "2020-06-28 22:45:12 UTC"
--- Present 1593384312 % 1 ((>>) 1593384312 % 1 | {UTCTimeToPosix 1593384312 % 1 | 2020-06-28 22:45:12 UTC})
--- PresentT (1593384312 % 1)
---
--- >>> pz @(Rescan "^Date\\((\\d+)([^\\)]+)\\)" Id >> Head Id >> Snd Id >> ((ReadP Integer (Id !! 0) >> PosixToUTCTime (Id % 1000)) &&& ReadP TimeZone (Id !! 1))) "Date(1530144000000+0530)"
--- PresentT (2018-06-28 00:00:00 UTC,+0530)
---
--- not so useful: instead use ParseTimeP FormatTimeP with %s %q %z etc
---
--- >>> pz @(ParseTimeP ZonedTime "%s%Q%z" Id)  "153014400.000+0530"
--- PresentT 1974-11-07 05:30:00 +0530
---
-data UTCTimeToPosix p
-
-instance ( PP p x ~ UTCTime
-         , P p x
-         ) => P (UTCTimeToPosix p) x where
-  type PP (UTCTimeToPosix p) x = Rational
-  eval _ opts x = do
-    let msg0 = "UTCTimeToPosix"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = toRational $ P.utcTimeToPOSIXSeconds p
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
--- | uses the 'Read' of the given type \'t\' and \'p\' which points to the content to read
---
--- >>> pz @(ReadP Rational Id) "4 % 5"
--- PresentT (4 % 5)
---
--- >>> pz @(Between (ReadP Day "2017-04-11") (ReadP Day "2018-12-30") (ReadP Day Id)) "2018-10-12"
--- TrueT
---
--- >>> pz @(Between (ReadP Day "2017-04-11") (ReadP Day "2018-12-30") (ReadP Day Id)) "2016-10-12"
--- FalseT
---
-data ReadP' t p
-
-instance (P p x
-        , PP p x ~ String
-        , Typeable (PP t x)
-        , Show (PP t x)
-        , Read (PP t x)
-        ) => P (ReadP' t p) x where
-  type PP (ReadP' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "ReadP " <> t
-        t = showT @(PP t x)
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right s ->
-        let hhs = [hh pp]
-        in case reads @(PP t x) s of
-           [(b,"")] -> mkNode opts (PresentT b) (msg0 <> " " ++ showL opts b) hhs
-           o -> mkNode opts (FailT (msg0 <> " (" ++ s ++ ")")) (showVerbose opts "" o) hhs
-
-data ReadP (t :: Type) p
-type ReadPT (t :: Type) p = ReadP' (Hole t) p
-
-instance P (ReadPT t p) x => P (ReadP t p) x where
-  type PP (ReadP t p) x = PP (ReadPT t p) x
-  eval _ = eval (Proxy @(ReadPT t p))
-
-
--- [] (a,s) (a,[])
-
--- | Read but returns the Maybe of the value and any remaining unparsed string
---
--- >>> pz @(ReadMaybe Int Id) "123x"
--- PresentT (Just (123,"x"))
---
--- >>> pz @(ReadMaybe Int Id) "123"
--- PresentT (Just (123,""))
---
--- >>> pz @(ReadMaybe Int Id) "x123"
--- PresentT Nothing
---
-data ReadMaybe' t p
-
--- not as good as ReadQ
--- type ReadZ' t p = ReadMaybe' t p >> JustFail "read failed" Id >> (Guard "oops" (Snd Id >> Null) >> Fst Id)
-
-instance (P p x
-        , PP p x ~ String
-        , Typeable (PP t x)
-        , Show (PP t x)
-        , Read (PP t x)
-        ) => P (ReadMaybe' t p) x where
-  type PP (ReadMaybe' t p) x = Maybe (PP t x, String)
-  eval _ opts x = do
-    let msg0 = "ReadMaybe " <> t
-        t = showT @(PP t x)
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right s ->
-        let msg1 = msg0 <> " (" <> s <> ")"
-            hhs = [hh pp]
-        in case reads @(PP t x) s of
-           [(b,rest)] -> mkNode opts (PresentT (Just (b,rest))) (lit01 opts msg1 b "" s) hhs
-           o -> mkNode opts (PresentT Nothing) (msg1 <> " failed" <> showVerbose opts " " o) hhs
-
-data ReadMaybe (t :: Type) p
-type ReadMaybeT (t :: Type) p = ReadMaybe' (Hole t) p
-
-instance P (ReadMaybeT t p) x => P (ReadMaybe t p) x where
-  type PP (ReadMaybe t p) x = PP (ReadMaybeT t p) x
-  eval _ = eval (Proxy @(ReadMaybeT t p))
-
--- | emulates ReadP
-data ReadQ' t p
-type ReadQT' t p = ReadMaybe' t p >> MaybeIn (Failp "read failed") (Guard "oops" (Snd Id >> Null) >> Fst Id)
-
-instance P (ReadQT' t p) x => P (ReadQ' t p) x where
-  type PP (ReadQ' t p) x = PP (ReadQT' t p) x
-  eval _ = eval (Proxy @(ReadQT' t p))
-
-data ReadQ (t :: Type) p
-type ReadQT (t :: Type) p = ReadQ' (Hole t) p
-
-instance P (ReadQT t p) x => P (ReadQ t p) x where
-  type PP (ReadQ t p) x = PP (ReadQT t p) x
-  eval _ = eval (Proxy @(ReadQT t p))
-
--- | similar to 'sum'
---
--- >>> pz @Sum [10,4,5,12,3,4]
--- PresentT 38
---
--- >>> pz @Sum []
--- PresentT 0
---
-data Sum
-
-instance ( Num a
-         , Show a
-         ) => P Sum [a] where
-  type PP Sum [a] = a
-  eval _ opts as =
-    let msg0 = "Sum"
-        v = sum as
-    in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
-
--- | similar to 'product'
---
--- >>> pz @Product [10,4,5,12,3,4]
--- PresentT 28800
---
--- >>> pz @Product []
--- PresentT 1
---
-data Product
-
-instance ( Num a
-         , Show a
-         ) => P Product [a] where
-  type PP Product [a] = a
-  eval _ opts as =
-    let msg0 = "Product"
-        v = product as
-    in pure $ mkNode opts (PresentT v) (show01 opts msg0 v as) []
-
--- | similar to 'minimum'
---
--- >>> pz @Min [10,4,5,12,3,4]
--- PresentT 3
---
--- >>> pz @Min []
--- FailT "empty list"
---
-data Min
-
-instance ( Ord a
-         , Show a
-         ) => P Min [a] where
-  type PP Min [a] = a
-  eval _ opts as' = do
-    let msg0 = "Min"
-    pure $ case as' of
-     [] -> mkNode opts (FailT "empty list") msg0 []
-     as@(_:_) ->
-       let v = minimum as
-       in mkNode opts (PresentT v) (show01 opts msg0 v as) []
-
--- | similar to 'maximum'
---
--- >>> pz @Max [10,4,5,12,3,4]
--- PresentT 12
---
--- >>> pz @Max []
--- FailT "empty list"
---
-
-data Max
-
-instance ( Ord a
-         , Show a
-         ) => P Max [a] where
-  type PP Max [a] = a
-  eval _ opts as' = do
-    let msg0 = "Max"
-    pure $ case as' of
-      [] -> mkNode opts (FailT "empty list") msg0 []
-      as@(_:_) ->
-        let v = maximum as
-        in mkNode opts (PresentT v) (show01 opts msg0 v as) []
-
--- | sort a list
---
--- >>> pz @(SortOn (Fst Id) Id) [(10,"abc"), (3,"def"), (4,"gg"), (10,"xyz"), (1,"z")]
--- PresentT [(1,"z"),(3,"def"),(4,"gg"),(10,"abc"),(10,"xyz")]
---
--- >>> pz @(SortBy (OrdP (Snd Id) (Fst Id)) Id) [(10,"ab"),(4,"x"),(20,"bbb")]
--- PresentT [(20,"bbb"),(10,"ab"),(4,"x")]
---
--- >>> pz @(SortBy 'LT Id) [1,5,2,4,7,0]
--- PresentT [1,5,2,4,7,0]
---
--- >>> pz @(SortBy 'GT Id) [1,5,2,4,7,0]
--- PresentT [0,7,4,2,5,1]
---
--- >>> pz @(SortBy ((Fst (Fst Id) ==! Fst (Snd Id)) <> (Snd (Fst Id) ==! Snd (Snd Id))) Id) [(10,"ab"),(4,"x"),(20,"bbb"),(4,"a"),(4,"y")]
--- PresentT [(4,"a"),(4,"x"),(4,"y"),(10,"ab"),(20,"bbb")]
---
--- >>> pz @(SortBy ((Fst (Fst Id) ==! Fst (Snd Id)) <> (Snd (Snd Id) ==! Snd (Fst Id))) Id) [(10,"ab"),(4,"x"),(20,"bbb"),(4,"a"),(4,"y")]
--- PresentT [(4,"y"),(4,"x"),(4,"a"),(10,"ab"),(20,"bbb")]
---
-data SortBy p q
-
-type SortByHelperT p = Partition (p == 'GT) Id
-
-instance (P p (a,a)
-        , P q x
-        , Show a
-        , PP q x ~ [a]
-        , PP p (a,a) ~ Ordering
-        ) => P (SortBy p q) x where
-  type PP (SortBy p q) x = PP q x
-  eval _ opts x = do
-    let msg0 = "SortBy"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts (msg0 <> " q failed") qq [] of
-      Left e -> pure e
-      Right as -> do
-        let ff :: MonadEval m => [a] -> m (TT [a])
-            ff = \case
-                [] -> pure $ mkNode opts (PresentT mempty) (msg0 <> " empty") [hh qq]
-                [w] -> pure $ mkNode opts (PresentT [w]) (msg0 <> " one element " <> showL opts w) [hh qq]
-                w:ys@(_:_) -> do
-                  pp <- evalHide (Proxy @(SortByHelperT p)) opts (map (w,) ys)
-                  case getValueLR opts msg0 pp [hh qq] of
-                    Left e -> pure e
-                    Right (ll', rr') -> do
-                      lhs <- ff (map snd ll')
-                      case getValueLR opts msg0 lhs [hh qq, hh pp] of
-                        Left _ -> pure lhs -- dont rewrap
-                        Right ll -> do
-                          rhs <- ff (map snd rr')
-                          case getValueLR opts msg0 rhs [hh qq, hh pp, hh lhs] of
-                            Left _ -> pure rhs
-                            Right rr ->
-                              pure $  mkNode opts (PresentT (ll ++ w : rr))
-                                     (msg0 <> " lhs=" <> showL opts ll <> " pivot " <> show w <> " rhs=" <> showL opts rr)
-                                     (hh pp : [hh lhs | length ll > 1] ++ [hh rhs | length rr > 1])
-        ret <- ff as
-        pure $ case getValueLR opts msg0 ret [hh qq] of
-          Left _e -> ret -- dont rewrap else will double up messages: already handled
-          Right xs -> mkNode opts (_tBool ret) (msg0 <> " " <> showL opts xs) [hh qq, hh ret]
-
-data SortOn p q
-type SortOnT p q = SortBy (OrdA p) q
-
-instance P (SortOnT p q) x => P (SortOn p q) x where
-  type PP (SortOn p q) x = PP (SortOnT p q) x
-  eval _ = eval (Proxy @(SortOnT p q))
-
-data SortOnDesc p q
-type SortOnDescT p q = SortBy (Swap >> OrdA p) q
-
-instance P (SortOnDescT p q) x => P (SortOnDesc p q) x where
-  type PP (SortOnDesc p q) x = PP (SortOnDescT p q) x
-  eval _ = eval (Proxy @(SortOnDescT p q))
-
--- | similar to 'length'
---
--- >>> pz @Len [10,4,5,12,3,4]
--- PresentT 6
---
--- >>> pz @Len []
--- PresentT 0
---
-data Len
-instance ( Show a
-         , as ~ [a]
-         ) => P Len as where
-  type PP Len as = Int
-  eval _ opts as =
-    let msg0 = "Len"
-        n = length as
-    in pure $ mkNode opts (PresentT n) (show01 opts msg0 n as) []
-
--- | similar to 'length' for 'Foldable' instances
---
--- >>> pz @(Length Id) (Left "aa")
--- PresentT 0
---
--- >>> pz @(Length Id) (Right "aa")
--- PresentT 1
---
--- >>> pz @(Length (Right' Id)) (Right "abcd")
--- PresentT 4
---
--- >>> pz @(Length (Thd (Snd Id))) (True,(23,'x',[10,9,1,3,4,2]))
--- PresentT 6
---
-data Length p
-
-instance (PP p x ~ t a
-        , P p x
-        , Show (t a)
-        , Foldable t) => P (Length p) x where
-  type PP (Length p) x = Int
-  eval _ opts x = do
-    let msg0 = "Length"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-            let n = length p
-            in mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
-
--- | similar to 'fst'
---
--- >>> pz @(Fst Id) (10,"Abc")
--- PresentT 10
---
--- >>> pz @(Fst Id) (10,"Abc",'x')
--- PresentT 10
---
--- >>> pz @(Fst Id) (10,"Abc",'x',False)
--- PresentT 10
---
-data Fst p
-
-instance (Show (ExtractL1T (PP p x))
-        , ExtractL1C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (Fst p) x where
-  type PP (Fst p) x = ExtractL1T (PP p x)
-  eval _ opts x = do
-    let msg0 = "Fst"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL1C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data L1 p
-type L1T p = Fst p
-
-instance P (L1T p) x => P (L1 p) x where
-  type PP (L1 p) x = PP (L1T p) x
-  eval _ = eval (Proxy @(L1T p))
-
-class ExtractL1C tp where
-  type ExtractL1T tp
-  extractL1C :: tp -> ExtractL1T tp
-instance ExtractL1C (a,b) where
-  type ExtractL1T (a,b) = a
-  extractL1C (a,_) = a
-instance ExtractL1C (a,b,c) where
-  type ExtractL1T (a,b,c) = a
-  extractL1C (a,_,_) = a
-instance ExtractL1C (a,b,c,d) where
-  type ExtractL1T (a,b,c,d) = a
-  extractL1C (a,_,_,_) = a
-instance ExtractL1C (a,b,c,d,e) where
-  type ExtractL1T (a,b,c,d,e) = a
-  extractL1C (a,_,_,_,_) = a
-instance ExtractL1C (a,b,c,d,e,f) where
-  type ExtractL1T (a,b,c,d,e,f) = a
-  extractL1C (a,_,_,_,_,_) = a
-
--- | similar to 'snd'
---
--- >>> pz @(Snd Id) (10,"Abc")
--- PresentT "Abc"
---
--- >>> pz @(Snd Id) (10,"Abc",True)
--- PresentT "Abc"
---
-data Snd p
-
-instance (Show (ExtractL2T (PP p x))
-        , ExtractL2C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (Snd p) x where
-  type PP (Snd p) x = ExtractL2T (PP p x)
-  eval _ opts x = do
-    let msg0 = "Snd"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL2C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data L2 p
-type L2T p = Snd p
-
-instance P (L2T p) x => P (L2 p) x where
-  type PP (L2 p) x = PP (L2T p) x
-  eval _ = eval (Proxy @(L2T p))
-
-class ExtractL2C tp where
-  type ExtractL2T tp
-  extractL2C :: tp -> ExtractL2T tp
-instance ExtractL2C (a,b) where
-  type ExtractL2T (a,b) = b
-  extractL2C (_,b) = b
-instance ExtractL2C (a,b,c) where
-  type ExtractL2T (a,b,c) = b
-  extractL2C (_,b,_) = b
-instance ExtractL2C (a,b,c,d) where
-  type ExtractL2T (a,b,c,d) = b
-  extractL2C (_,b,_,_) = b
-instance ExtractL2C (a,b,c,d,e) where
-  type ExtractL2T (a,b,c,d,e) = b
-  extractL2C (_,b,_,_,_) = b
-instance ExtractL2C (a,b,c,d,e,f) where
-  type ExtractL2T (a,b,c,d,e,f) = b
-  extractL2C (_,b,_,_,_,_) = b
-
--- | similar to 3rd element in a n-tuple
---
--- >>> pz @(Thd Id) (10,"Abc",133)
--- PresentT 133
---
--- >>> pz @(Thd Id) (10,"Abc",133,True)
--- PresentT 133
---
-data Thd p
-
-instance (Show (ExtractL3T (PP p x))
-        , ExtractL3C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (Thd p) x where
-  type PP (Thd p) x = ExtractL3T (PP p x)
-  eval _ opts x = do
-    let msg0 = "Thd"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL3C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data L3 p
-type L3T p = Thd p
-
-instance P (L3T p) x => P (L3 p) x where
-  type PP (L3 p) x = PP (L3T p) x
-  eval _ = eval (Proxy @(L3T p))
-
-class ExtractL3C tp where
-  type ExtractL3T tp
-  extractL3C :: tp -> ExtractL3T tp
-instance ExtractL3C (a,b) where
-  type ExtractL3T (a,b) = GL.TypeError ('GL.Text "Thd doesn't work for 2-tuples")
-  extractL3C _ = errorInProgram "Thd doesn't work for 2-tuples"
-instance ExtractL3C (a,b,c) where
-  type ExtractL3T (a,b,c) = c
-  extractL3C (_,_,c) = c
-instance ExtractL3C (a,b,c,d) where
-  type ExtractL3T (a,b,c,d) = c
-  extractL3C (_,_,c,_) = c
-instance ExtractL3C (a,b,c,d,e) where
-  type ExtractL3T (a,b,c,d,e) = c
-  extractL3C (_,_,c,_,_) = c
-instance ExtractL3C (a,b,c,d,e,f) where
-  type ExtractL3T (a,b,c,d,e,f) = c
-  extractL3C (_,_,c,_,_,_) = c
-
--- | similar to 4th element in a n-tuple
---
--- >>> pz @(L4 Id) (10,"Abc",'x',True)
--- PresentT True
---
--- >>> pz @(L4 (Fst (Snd Id))) ('x',((10,"Abc",'x',999),"aa",1),9)
--- PresentT 999
---
-data L4 p
-
-instance (Show (ExtractL4T (PP p x))
-        , ExtractL4C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (L4 p) x where
-  type PP (L4 p) x = ExtractL4T (PP p x)
-  eval _ opts x = do
-    let msg0 = "L4"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL4C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-class ExtractL4C tp where
-  type ExtractL4T tp
-  extractL4C :: tp -> ExtractL4T tp
-instance ExtractL4C (a,b) where
-  type ExtractL4T (a,b) = GL.TypeError ('GL.Text "L4 doesn't work for 2-tuples")
-  extractL4C _ = errorInProgram "L4 doesn't work for 2-tuples"
-instance ExtractL4C (a,b,c) where
-  type ExtractL4T (a,b,c) = GL.TypeError ('GL.Text "L4 doesn't work for 3-tuples")
-  extractL4C _ = errorInProgram "L4 doesn't work for 3-tuples"
-instance ExtractL4C (a,b,c,d) where
-  type ExtractL4T (a,b,c,d) = d
-  extractL4C (_,_,_,d) = d
-instance ExtractL4C (a,b,c,d,e) where
-  type ExtractL4T (a,b,c,d,e) = d
-  extractL4C (_,_,_,d,_) = d
-instance ExtractL4C (a,b,c,d,e,f) where
-  type ExtractL4T (a,b,c,d,e,f) = d
-  extractL4C (_,_,_,d,_,_) = d
-
--- | similar to 5th element in a n-tuple
---
--- >>> pz @(L5 Id) (10,"Abc",'x',True,1)
--- PresentT 1
---
-data L5 p
-
-instance (Show (ExtractL5T (PP p x))
-        , ExtractL5C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (L5 p) x where
-  type PP (L5 p) x = ExtractL5T (PP p x)
-  eval _ opts x = do
-    let msg0 = "L5"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL5C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-class ExtractL5C tp where
-  type ExtractL5T tp
-  extractL5C :: tp -> ExtractL5T tp
-instance ExtractL5C (a,b) where
-  type ExtractL5T (a,b) = GL.TypeError ('GL.Text "L5 doesn't work for 2-tuples")
-  extractL5C _ = errorInProgram "L5 doesn't work for 2-tuples"
-instance ExtractL5C (a,b,c) where
-  type ExtractL5T (a,b,c) = GL.TypeError ('GL.Text "L5 doesn't work for 3-tuples")
-  extractL5C _ = errorInProgram "L5 doesn't work for 3-tuples"
-instance ExtractL5C (a,b,c,d) where
-  type ExtractL5T (a,b,c,d) = GL.TypeError ('GL.Text "L5 doesn't work for 4-tuples")
-  extractL5C _ = errorInProgram "L5 doesn't work for 4-tuples"
-instance ExtractL5C (a,b,c,d,e) where
-  type ExtractL5T (a,b,c,d,e) = e
-  extractL5C (_,_,_,_,e) = e
-instance ExtractL5C (a,b,c,d,e,f) where
-  type ExtractL5T (a,b,c,d,e,f) = e
-  extractL5C (_,_,_,_,e,_) = e
-
-
--- | similar to 6th element in a n-tuple
---
--- >>> pz @(L6 Id) (10,"Abc",'x',True,1,99)
--- PresentT 99
---
-data L6 p
-
-instance (Show (ExtractL6T (PP p x))
-        , ExtractL6C (PP p x)
-        , P p x
-        , Show (PP p x)
-        ) => P (L6 p) x where
-  type PP (L6 p) x = ExtractL6T (PP p x)
-  eval _ opts x = do
-    let msg0 = "L6"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = extractL6C p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-class ExtractL6C tp where
-  type ExtractL6T tp
-  extractL6C :: tp -> ExtractL6T tp
-instance ExtractL6C (a,b) where
-  type ExtractL6T (a,b) = GL.TypeError ('GL.Text "L6 doesn't work for 2-tuples")
-  extractL6C _ = errorInProgram "L6 doesn't work for 2-tuples"
-instance ExtractL6C (a,b,c) where
-  type ExtractL6T (a,b,c) = GL.TypeError ('GL.Text "L6 doesn't work for 3-tuples")
-  extractL6C _ = errorInProgram "L6 doesn't work for 3-tuples"
-instance ExtractL6C (a,b,c,d) where
-  type ExtractL6T (a,b,c,d) = GL.TypeError ('GL.Text "L6 doesn't work for 4-tuples")
-  extractL6C _ = errorInProgram "L6 doesn't work for 4-tuples"
-instance ExtractL6C (a,b,c,d,e) where
-  type ExtractL6T (a,b,c,d,e) = GL.TypeError ('GL.Text "L6 doesn't work for 5-tuples")
-  extractL6C _ = errorInProgram "L6 doesn't work for 5-tuples"
-instance ExtractL6C (a,b,c,d,e,f) where
-  type ExtractL6T (a,b,c,d,e,f) = f
-  extractL6C (_,_,_,_,_,f) = f
-
-
--- | 'fromString' function where you need to provide the type \'t\' of the result
---
--- >>> :set -XFlexibleContexts
--- >>> pz @(FromString (Identity _) Id) "abc"
--- PresentT (Identity "abc")
---
--- >>> pz @(FromString (Seq.Seq Char) Id) "abc"
--- PresentT (fromList "abc")
-data FromString' t s
-
-instance (P s a
-        , PP s a ~ String
-        , Show (PP t a)
-        , IsString (PP t a)
-        ) => P (FromString' t s) a where
-  type PP (FromString' t s) a = PP t a
-  eval _ opts a = do
-    let msg0 = "FromString"
-    ss <- eval (Proxy @s) opts a
-    pure $ case getValueLR opts msg0 ss [] of
-      Left e -> e
-      Right s ->
-        let b = fromString @(PP t a) s
-        in mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) [hh ss]
-
-data FromString (t :: Type) p
-type FromStringPT (t :: Type) p = FromString' (Hole t) p
-
-instance P (FromStringPT t p) x => P (FromString t p) x where
-  type PP (FromString t p) x = PP (FromStringPT t p) x
-  eval _ = eval (Proxy @(FromStringPT t p))
-
-
--- | 'fromInteger' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(FromInteger (SG.Sum _) Id) 23
--- PresentT (Sum {getSum = 23})
---
--- >>> pz @(FromInteger Rational 44) 12
--- PresentT (44 % 1)
---
--- >>> pz @(FromInteger Rational Id) 12
--- PresentT (12 % 1)
---
-data FromInteger' t n
-
-instance (Num (PP t a)
-        , Integral (PP n a)
-        , P n a
-        , Show (PP t a)
-        ) => P (FromInteger' t n) a where
-  type PP (FromInteger' t n) a = PP t a
-  eval _ opts a = do
-    let msg0 = "FromInteger"
-    nn <- eval (Proxy @n) opts a
-    pure $ case getValueLR opts msg0 nn [] of
-      Left e -> e
-      Right n ->
-        let b = fromInteger (fromIntegral n)
-        in mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) [hh nn]
-
-data FromInteger (t :: Type) p
-type FromIntegerT (t :: Type) p = FromInteger' (Hole t) p
---type FromIntegerP n = FromInteger' Unproxy n
-
-instance P (FromIntegerT t p) x => P (FromInteger t p) x where
-  type PP (FromInteger t p) x = PP (FromIntegerT t p) x
-  eval _ = eval (Proxy @(FromIntegerT t p))
-
--- | 'fromIntegral' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(FromIntegral (SG.Sum _) Id) 23
--- PresentT (Sum {getSum = 23})
-data FromIntegral' t n
-
-instance (Num (PP t a)
-        , Integral (PP n a)
-        , P n a
-        , Show (PP t a)
-        , Show (PP n a)
-        ) => P (FromIntegral' t n) a where
-  type PP (FromIntegral' t n) a = PP t a
-  eval _ opts a = do
-    let msg0 = "FromIntegral"
-    nn <- eval (Proxy @n) opts a
-    pure $ case getValueLR opts msg0 nn [] of
-      Left e -> e
-      Right n ->
-        let b = fromIntegral n
-        in mkNode opts (PresentT b) (show01 opts msg0 b n) [hh nn]
-
-data FromIntegral (t :: Type) p
-type FromIntegralT (t :: Type) p = FromIntegral' (Hole t) p
-
-instance P (FromIntegralT t p) x => P (FromIntegral t p) x where
-  type PP (FromIntegral t p) x = PP (FromIntegralT t p) x
-  eval _ = eval (Proxy @(FromIntegralT t p))
-
--- | 'toRational' function
---
--- >>> pz @(ToRational Id) 23.5
--- PresentT (47 % 2)
-
-data ToRational p
-
-instance (a ~ PP p x
-         , Show a
-         , Real a
-         , P p x)
-   => P (ToRational p) x where
-  type PP (ToRational p) x = Rational
-  eval _ opts x = do
-    let msg0 = "ToRational"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right a ->
-        let r = toRational a
-        in mkNode opts (PresentT r) (show01 opts msg0 r a) [hh pp]
-
--- | 'fromRational' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(FromRational Rational Id) 23.5
--- PresentT (47 % 2)
-data FromRational' t r
-
-instance (P r a
-        , PP r a ~ Rational
-        , Show (PP t a)
-        , Fractional (PP t a)
-        ) => P (FromRational' t r) a where
-  type PP (FromRational' t r) a = PP t a
-  eval _ opts a = do
-    let msg0 = "FromRational"
-    rr <- eval (Proxy @r) opts a
-    pure $ case getValueLR opts msg0 rr [] of
-      Left e -> e
-      Right r ->
-        let b = fromRational @(PP t a) r
-        in mkNode opts (PresentT b) (show01 opts msg0 b r) [hh rr]
-
-data FromRational (t :: Type) p
-type FromRationalT (t :: Type) p = FromRational' (Hole t) p
-
-instance P (FromRationalT t p) x => P (FromRational t p) x where
-  type PP (FromRational t p) x = PP (FromRationalT t p) x
-  eval _ = eval (Proxy @(FromRationalT t p))
-
--- | 'truncate' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(Truncate Int Id) (23 % 5)
--- PresentT 4
-data Truncate' t p
-
-instance (Show (PP p x)
-        , P p x
-        , Show (PP t x)
-        , RealFrac (PP p x)
-        , Integral (PP t x)
-        ) => P (Truncate' t p) x where
-  type PP (Truncate' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "Truncate"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = truncate p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data Truncate (t :: Type) p
-type TruncateT (t :: Type) p = Truncate' (Hole t) p
-
-instance P (TruncateT t p) x => P (Truncate t p) x where
-  type PP (Truncate t p) x = PP (TruncateT t p) x
-  eval _ = eval (Proxy @(TruncateT t p))
-
--- | 'ceiling' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(Ceiling Int Id) (23 % 5)
--- PresentT 5
-data Ceiling' t p
-
-instance (Show (PP p x)
-        , P p x
-        , Show (PP t x)
-        , RealFrac (PP p x)
-        , Integral (PP t x)
-        ) => P (Ceiling' t p) x where
-  type PP (Ceiling' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "Ceiling"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = ceiling p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data Ceiling (t :: Type) p
-type CeilingT (t :: Type) p = Ceiling' (Hole t) p
-
-instance P (CeilingT t p) x => P (Ceiling t p) x where
-  type PP (Ceiling t p) x = PP (CeilingT t p) x
-  eval _ = eval (Proxy @(CeilingT t p))
-
--- | 'floor' function where you need to provide the type \'t\' of the result
---
--- >>> pz @(Floor Int Id) (23 % 5)
--- PresentT 4
-data Floor' t p
-
-instance (Show (PP p x)
-        , P p x
-        , Show (PP t x)
-        , RealFrac (PP p x)
-        , Integral (PP t x)
-        ) => P (Floor' t p) x where
-  type PP (Floor' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "Floor"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = floor p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data Floor (t :: Type) p
-type FloorT (t :: Type) p = Floor' (Hole t) p
-
-instance P (FloorT t p) x => P (Floor t p) x where
-  type PP (Floor t p) x = PP (FloorT t p) x
-  eval _ = eval (Proxy @(FloorT t p))
--- | converts a value to a 'Proxy': the same as '\'Proxy'
---
--- >>> pz @MkProxy 'x'
--- PresentT Proxy
---
-data MkProxy
-
-instance Show a => P MkProxy a where
-  type PP MkProxy a = Proxy a
-  eval _ opts a =
-    let msg0 = "MkProxy"
-        b = Proxy @a
-    in pure $ mkNode opts (PresentT b) (msg0 <> showVerbose opts " | " a) []
-
--- | processes a type level list predicates running each in sequence: see 'Predicate.>>'
---
--- >>> pz @(Do [Pred Id, ShowP Id, Id &&& Len]) 9876543
--- PresentT ("9876542",7)
---
--- >>> pz @(Do '[W 123, W "xyz", Len &&& Id, Pred Id *** Id<>Id]) ()
--- PresentT (2,"xyzxyz")
---
-data Do (ps :: [k])
-
-instance (P (DoExpandT ps) a) => P (Do ps) a where
-  type PP (Do ps) a = PP (DoExpandT ps) a
-  eval _ = eval (Proxy @(DoExpandT ps))
-
-type family DoExpandT (ps :: [k]) :: Type where
-  DoExpandT '[] = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
-  DoExpandT '[p] = Id >> p -- need this else fails cos 1 is nat and would mean that the result is nat not Type!
-  -- if p >> Id then turns TrueT to PresentT True
-  DoExpandT (p ': p1 ': ps) = p >> DoExpandT (p1 ': ps)
-
--- | Convenient method to convert a value \'p\' to a 'Maybe' based on a predicate '\b\'
--- if '\b\' then Just \'p'\ else Nothing
---
--- >>> pz @(MaybeBool (Id > 4) Id) 24
--- PresentT (Just 24)
---
--- >>> pz @(MaybeBool (Id > 4) Id) (-5)
--- PresentT Nothing
---
-data MaybeBool b p
-
-instance (Show (PP p a)
-        , P b a
-        , P p a
-        , PP b a ~ Bool
-        ) => P (MaybeBool b p) a where
-  type PP (MaybeBool b p) a = Maybe (PP p a)
-  eval _ opts z = do
-    let msg0 = "MaybeBool"
-    bb <- evalBool (Proxy @b) opts z
-    case getValueLR opts (msg0 <> " b failed") bb [] of
-      Left e -> pure e
-      Right True -> do
-        pp <- eval (Proxy @p) opts z
-        pure $ case getValueLR opts (msg0 <> " p failed") pp [hh bb] of
-          Left e -> e
-          Right p -> mkNode opts (PresentT (Just p)) (msg0 <> "(False)" <> " Just " <> showL opts p) [hh bb, hh pp]
-      Right False -> pure $ mkNode opts (PresentT Nothing) (msg0 <> "(True)") [hh bb]
-
--- | Convenient method to convert a \'p\' or '\q'\ to a 'Either' based on a predicate '\b\'
--- if \'b\' then Right \'p\' else Left '\q\'
---
--- >>> pz @(EitherBool (Fst Id > 4) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (24,(-1,999))
--- PresentT (Right 999)
---
--- >>> pz @(EitherBool (Fst Id > 4) (Fst (Snd Id)) (Snd (Snd Id))) (1,(-1,999))
--- PresentT (Left (-1))
---
-data EitherBool b p q
-
-instance (Show (PP p a)
-        , P p a
-        , Show (PP q a)
-        , P q a
-        , P b a
-        , PP b a ~ Bool
-        ) => P (EitherBool b p q) a where
-  type PP (EitherBool b p q) a = Either (PP p a) (PP q a)
-  eval _ opts z = do
-    let msg0 = "EitherBool"
-    bb <- evalBool (Proxy @b) opts z
-    case getValueLR opts (msg0 <> " b failed") bb [] of
-      Left e -> pure e
-      Right False -> do
-        pp <- eval (Proxy @p) opts z
-        pure $ case getValueLR opts (msg0 <> " p failed") pp [hh bb] of
-          Left e -> e
-          Right p -> mkNode opts (PresentT (Left p)) (msg0 <> "(False)" <> " Left " <> showL opts p) [hh bb, hh pp]
-      Right True -> do
-        qq <- eval (Proxy @q) opts z
-        pure $ case getValueLR opts (msg0 <> " q failed") qq [hh bb] of
-          Left e -> e
-          Right q -> mkNode opts (PresentT (Right q)) (msg0 <> "(True)" <> " Right " <> showL opts q) [hh bb, hh qq]
-
--- | pad \'q\' with '\n'\ values from '\p'\
---
--- >>> pz @(PadL 5 999 Id) [12,13]
--- PresentT [999,999,999,12,13]
---
--- >>> pz @(PadR 5 (Fst Id) '[12,13]) (999,'x')
--- PresentT [12,13,999,999,999]
---
--- >>> pz @(PadR 2 (Fst Id) '[12,13,14]) (999,'x')
--- PresentT [12,13,14]
---
-data PadImpl (left :: Bool) n p q
-
-instance (P n a
-        , GetBool left
-        , Integral (PP n a)
-        , [PP p a] ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        ) => P (PadImpl left n p q) a where
-  type PP (PadImpl left n p q) a = PP q a
-  eval _ opts a = do
-    let msg0 = "Pad" <> (if lft then "L" else "R")
-        lft = getBool @left
-    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
-    case lr of
-      Left e -> pure e
-      Right (fromIntegral -> n,p,nn,pp) -> do
-        let msg1 = msg0 <> " " <> showL opts n <> " pad=" <> show p
-            hhs = [hh nn, hh pp]
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts (msg1 <> " q failed") qq hhs of
-          Left e -> e
-          Right q ->
-            let l = length q
-                diff = if n<=l then 0 else n-l
-                bs = if lft
-                     then replicate diff p <> q
-                     else q <> replicate diff p
-            in mkNode opts (PresentT bs) (show01 opts msg1 bs q) (hhs <> [hh qq])
-
-data PadL n p q
-type PadLT n p q = PadImpl 'True n p q
-
-instance P (PadLT n p q) x => P (PadL n p q) x where
-  type PP (PadL n p q) x = PP (PadLT n p q) x
-  eval _ = eval (Proxy @(PadLT n p q))
-
-data PadR n p q
-type PadRT n p q = PadImpl 'False n p q
-
-instance P (PadRT n p q) x => P (PadR n p q) x where
-  type PP (PadR n p q) x = PP (PadRT n p q) x
-  eval _ = eval (Proxy @(PadRT n p q))
-
--- | split a list \'p\' into parts using the lengths in the type level list \'ns\'
---
--- >>> pz @(SplitAts '[2,3,1,1] Id) "hello world"
--- PresentT ["he","llo"," ","w","orld"]
---
--- >>> pz @(SplitAts '[2] Id) "hello world"
--- PresentT ["he","llo world"]
---
--- >>> pz @(SplitAts '[10,1,1,5] Id) "hello world"
--- PresentT ["hello worl","d","",""]
---
-data SplitAts ns p
-
-instance (P ns x
-        , P p x
-        , PP p x ~ [a]
-        , Show n
-        , Show a
-        , PP ns x ~ [n]
-        , Integral n
-        ) => P (SplitAts ns p) x where
-  type PP (SplitAts ns p) x = [PP p x]
-  eval _ opts x = do
-    let msg0 = "SplitAts"
-    lr <- runPQ msg0 (Proxy @ns) (Proxy @p) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (ns,p,nn,pp) ->
-        let zs = foldr (\n k s -> let (a,b) = splitAtNeg (fromIntegral n) s
-                              in a:k b
-                   ) (\as -> if null as then [] else [as]) ns p
-        in mkNode opts (PresentT zs) (show01' opts msg0 zs "ns=" ns <> showVerbose opts " | " p) [hh nn, hh pp]
-
--- | similar to 'splitAt'
---
--- >>> pz @(SplitAt 4 Id) "hello world"
--- PresentT ("hell","o world")
---
--- >>> pz @(SplitAt 20 Id) "hello world"
--- PresentT ("hello world","")
---
--- >>> pz @(SplitAt 0 Id) "hello world"
--- PresentT ("","hello world")
---
--- >>> pz @(SplitAt (Snd Id) (Fst Id)) ("hello world",4)
--- PresentT ("hell","o world")
---
--- >>> pz @(SplitAt (Negate 2) Id) "hello world"
--- PresentT ("hello wor","ld")
---
-data SplitAt n p
-
-instance (PP p a ~ [b]
-        , P n a
-        , P p a
-        , Show b
-        , Integral (PP n a)
-        ) => P (SplitAt n p) a where
-  type PP (SplitAt n p) a = (PP p a, PP p a)
-  eval _ opts a = do
-    let msg0 = "SplitAt"
-    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
-    pure $ case lr of
-      Left e -> e -- (Left e, tt')
-      Right (fromIntegral -> n,p,pp,qq) ->
-        let msg1 = msg0 <> " " <> showL opts n <> " " <> showL opts p
-            ret = splitAtNeg n p
-       in mkNode opts (PresentT ret) (show01' opts msg1 ret "n=" n <> showVerbose opts " | " p) [hh pp, hh qq]
-
-splitAtNeg :: Int -> [a] -> ([a], [a])
-splitAtNeg n as = splitAt (if n<0 then length as + n else n) as
-
-
-data Take n p
-type TakeT n p = Fst (SplitAt n p)
-
-instance P (TakeT n p) x => P (Take n p) x where
-  type PP (Take n p) x = PP (TakeT n p) x
-  eval _ = eval (Proxy @(TakeT n p))
-
-data Drop n p
-type DropT n p = Snd (SplitAt n p)
-
-instance P (DropT n p) x => P (Drop n p) x where
-  type PP (Drop n p) x = PP (DropT n p) x
-  eval _ = eval (Proxy @(DropT n p))
-
---type Tail = Uncons >> 'Just (Snd Id)
---type Head = Uncons >> 'Just (Fst Id)
---type Init = Unsnoc >> 'Just (Fst Id)
---type Last = Unsnoc >> 'Just (Snd Id)
-
--- | similar to 'Control.Arrow.&&&'
-data p &&& q
-infixr 3 &&&
-type WAmpT p q = W '(p, q)
-
-instance P (WAmpT p q) x => P (p &&& q) x where
-  type PP (p &&& q) x = PP (WAmpT p q) x
-  eval _ = eval (Proxy @(WAmpT p q))
-
--- | similar to 'Control.Arrow.***'
---
--- >>> pz @(Pred Id *** ShowP Id) (13, True)
--- PresentT (12,"True")
---
--- >>> pl @(FlipT (***) Len (Id * 12)) (99,"cdef")
--- Present (1188,4) ((***) (1188,4) | (99,"cdef"))
--- PresentT (1188,4)
---
-data p *** q
-infixr 3 ***
-
-instance (Show (PP p a)
-        , Show (PP q b)
-        , P p a
-        , P q b
-        , Show a
-        , Show b
-        ) => P (p *** q) (a,b) where
-  type PP (p *** q) (a,b) = (PP p a, PP q b)
-  eval _ opts (a,b) = do
-    let msg0 = "(***)"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right a1 -> do
-        qq <- eval (Proxy @q) opts b
-        pure $ case getValueLR opts msg0 qq [hh pp] of
-          Left e -> e
-          Right b1 -> mkNode opts (PresentT (a1,b1)) (msg0 <> " " <> showL opts (a1,b1) <> showVerbose opts " | " (a,b)) [hh pp, hh qq]
-
-data First p
-type FirstT p = p *** I
-
-instance P (FirstT p) x => P (First p) x where
-  type PP (First p) x = PP (FirstT p) x
-  eval _ = eval (Proxy @(FirstT p))
-
-data Second q
-type SecondT q = I *** q
-
-instance P (SecondT q) x => P (Second q) x where
-  type PP (Second q) x = PP (SecondT q) x
-  eval _ = eval (Proxy @(SecondT q))
-
--- | similar 'Control.Arrow.|||'
---
--- >>> pz @(Pred Id ||| Id) (Left 13)
--- PresentT 12
---
--- >>> pz @(ShowP Id ||| Id) (Right "hello")
--- PresentT "hello"
---
-data p ||| q
-infixr 2 |||
-type EitherIn p q = p ||| q
-
-instance (Show (PP p a)
-        , P p a
-        , P q b
-        , PP p a ~ PP q b
-        , Show a
-        , Show b
-        ) => P (p ||| q) (Either a b) where
-  type PP (p ||| q) (Either a b) = PP p a
-  eval _ opts lr = do
-    let msg0 = "(|||)"
-    case lr of
-      Left a -> do
-        pp <- eval (Proxy @p) opts a
-        pure $ case getValueLR opts msg0 pp [] of
-          Left e -> e
-          Right a1 -> let msg1 = msg0 ++ " Left"
-                      in mkNode opts (_tBool pp) (show01 opts msg1 a1 a) [hh pp]
-      Right a -> do
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg0 qq [] of
-          Left e -> e
-          Right a1 ->
-            let msg1 = msg0 ++ " Right"
-            in mkNode opts (_tBool qq) (show01 opts msg1 a1 a) [hh qq]
-
--- | similar to 'isLeft'
---
--- >>> pz @(IsLeft Id) (Right 123)
--- FalseT
---
--- >>> pz @(IsLeft Id) (Left 'a')
--- TrueT
---
-data IsLeft p
-
-instance ( P p x
-         , PP p x ~ Either a b
-         ) => P (IsLeft p) x where
-  type PP (IsLeft p) x = Bool
-  eval _ opts x = do
-    let msg0 = "IsLeft"
-    pp <- eval (Proxy @p) opts x
-    let hhs = [hh pp]
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right (Left _) -> mkNodeB opts True msg0 hhs
-      Right (Right _) -> mkNodeB opts False msg0 hhs
-
--- | similar to 'isRight'
---
--- >>> pz @(IsRight Id) (Right 123)
--- TrueT
---
--- >>> pz @(IsRight Id) (Left "aa")
--- FalseT
---
-
-data IsRight p
-
-instance ( P p x
-         , PP p x ~ Either a b
-         ) => P (IsRight p) x where
-  type PP (IsRight p) x = Bool
-  eval _ opts x = do
-    let msg0 = "IsRight"
-    pp <- eval (Proxy @p) opts x
-    let hhs = [hh pp]
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right (Left _) -> mkNodeB opts False msg0 hhs
-      Right (Right _) -> mkNodeB opts True msg0 hhs
-
-
--- | similar 'Control.Arrow.+++'
---
--- >>> pz @(Pred Id +++ Id) (Left 13)
--- PresentT (Left 12)
---
--- >>> pz @(ShowP Id +++ Reverse) (Right "hello")
--- PresentT (Right "olleh")
---
-data p +++ q
-infixr 2 +++
-
-instance (Show (PP p a)
-        , Show (PP q b)
-        , P p a
-        , P q b
-        , Show a
-        , Show b
-        ) => P (p +++ q) (Either a b) where
-  type PP (p +++ q) (Either a b) = Either (PP p a) (PP q b)
-  eval _ opts lr = do
-    let msg0 = "(+++)"
-    case lr of
-      Left a -> do
-        pp <- eval (Proxy @p) opts a
-        pure $ case getValueLR opts msg0 pp [] of
-          Left e -> e
-          Right a1 ->
-            let msg1 = msg0 ++ " Left"
-            in mkNode opts (PresentT (Left a1)) (msg1 <> " " <> showL opts a1 <> showVerbose opts " | " a) [hh pp]
-      Right a -> do
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg0 qq [] of
-          Left e -> e
-          Right a1 ->
-            let msg1 = msg0 ++ " Right"
-            in mkNode opts (PresentT (Right a1)) (msg1 <> " " <> showL opts a1 <> showVerbose opts " | " a) [hh qq]
-
-data Dup
-type DupT = W '(Id, Id)
-
-instance Show x => P Dup x where
-  type PP Dup x = PP DupT x
-  eval _ = eval (Proxy @DupT)
-
-data BinOp = BMult | BSub | BAdd deriving (Show,Eq)
-
-data p + q
-infixl 6 +
-
-type AddT p q = Bin 'BAdd p q
-
-instance P (AddT p q) x => P (p + q) x where
-  type PP (p + q) x = PP (AddT p q) x
-  eval _ = eval (Proxy @(AddT p q))
-
-data p - q
-infixl 6 -
-
-type SubT p q = Bin 'BSub p q
-
-instance P (SubT p q) x => P (p - q) x where
-  type PP (p - q) x = PP (SubT p q) x
-  eval _ = eval (Proxy @(SubT p q))
-
-data p * q
-infixl 7 *
-
-type MultT p q = Bin 'BMult p q
-
-instance P (MultT p q) x => P (p * q) x where
-  type PP (p * q) x = PP (MultT p q) x
-  eval _ = eval (Proxy @(MultT p q))
-
--- | similar to 'GHC.Real.(^)'
---
--- >>> pz @(Fst Id ^ Snd Id) (10,4)
--- PresentT 10000
---
-data p ^ q
-infixr 8 ^
-
-instance (P p a
-        , P q a
-        , Show (PP p a)
-        , Show (PP q a)
-        , Num (PP p a)
-        , Integral (PP q a)
-        ) => P (p ^ q) a where
-  type PP (p ^ q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "Pow"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg0 qq [hh pp] of
-          Left e -> e
-          Right q ->
-                let hhs = [hh pp, hh qq]
-                in if q < 0 then mkNode opts (FailT (msg0 <> " negative exponent")) "" hhs
-                   else let d = p ^ q
-                        in mkNode opts (PresentT d) (showL opts p <> " ^ " <> showL opts q <> " = " <> showL opts d) hhs
-
--- | similar to 'GHC.Float.(**)'
---
--- >>> pz @(Fst Id ** Snd Id) (10,4)
--- PresentT 10000.0
---
--- >>> pz @'(Prime Id,Id ^ 3,(FromIntegral _ Id) ** (FromRational _ (1 % 2))) 4
--- PresentT (False,64,2.0)
---
-data p ** q
-infixr 8 **
-
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Floating (PP p a)
-        , Ord (PP q a)
-        ) => P (p ** q) a where
-  type PP (p ** q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "Exp"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-         let hhs = [hh pp, hh qq]
-         in if q < 0 then mkNode opts (FailT (msg0 <> " negative exponent")) "" hhs
-            else if p == 0 && q == 0 then mkNode opts (FailT (msg0 <> " zero/zero")) "" hhs
-            else let d = p ** q
-                in mkNode opts (PresentT d) (showL opts p <> " ** " <> showL opts q <> " = " <> showL opts d) hhs
-
--- | similar to 'logBase'
---
--- >>> pz @(Fst Id `LogBase` Snd Id >> Truncate Int Id) (10,12345)
--- PresentT 4
---
-data LogBase p q
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP q a)
-        , Floating (PP q a)
-        , Ord (PP p a)
-        ) => P (LogBase p q) a where
-  type PP (LogBase p q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "LogBase"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-         let hhs = [hh pp, hh qq]
-         in if p <= 0 then mkNode opts (FailT (msg0 <> " non-positive base")) "" hhs
-            else let d = logBase p q
-                 in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p <> " " <> showL opts q <> " = " <> showL opts d) hhs
-
-data p > q
-infix 4 >
-
-instance P (Cmp 'CGt p q) x => P (p > q) x where
-  type PP (p > q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CGt p q))
-
-data p >= q
-infix 4 >=
-
-instance P (Cmp 'CGe p q) x => P (p >= q) x where
-  type PP (p >= q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CGe p q))
-
-data p == q
-infix 4 ==
-
-instance P (Cmp 'CEq p q) x => P (p == q) x where
-  type PP (p == q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CEq p q))
-
-data p <= q
-infix 4 <=
-
-instance P (Cmp 'CLe p q) x => P (p <= q) x where
-  type PP (p <= q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CLe p q))
-
-data p < q
-infix 4 <
-
-instance P (Cmp 'CLt p q) x => P (p < q) x where
-  type PP (p < q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CLt p q))
-
-data p /= q
-infix 4 /=
-
-instance P (Cmp 'CNe p q) x => P (p /= q) x where
-  type PP (p /= q) x = Bool
-  eval _ = evalBool (Proxy @(Cmp 'CNe p q))
-
---type p + q = Bin 'BAdd p q
---type p - q = Bin 'BSub p q
---type p * q = Bin 'BMult p q
-
---type p > q = Cmp 'CGt p q
---type p >= q = Cmp 'CGe p q
---type p == q = Cmp 'CEq p q
---type p /= q = Cmp 'CNe p q
---type p <= q = Cmp 'CLe p q
---type p < q = Cmp 'CLt p q
-
-type Gt n = I > n
-type Ge n = I >= n
-type Same n = I == n
-type Le n = I <= n
-type Lt n = I < n
-type Ne n = I /= n
-
---type p >~ q = CmpI 'CGt p q
---type p >=~ q = CmpI 'CGe p q
---type p ==~ q = CmpI 'CEq p q
---type p <=~ q = CmpI 'CLe p q
---type p <~ q = CmpI 'CLt p q
---type p /=~ q = CmpI 'CNe p q
-
-data p >~ q
-infix 4 >~
-
-instance P (CmpI 'CGt p q) x => P (p >~ q) x where
-  type PP (p >~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CGt p q))
-
-data p >=~ q
-infix 4 >=~
-
-instance P (CmpI 'CGe p q) x => P (p >=~ q) x where
-  type PP (p >=~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CGe p q))
-
-data p ==~ q
-infix 4 ==~
-
-instance P (CmpI 'CEq p q) x => P (p ==~ q) x where
-  type PP (p ==~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CEq p q))
-
-data p <=~ q
-infix 4 <=~
-
-instance P (CmpI 'CLe p q) x => P (p <=~ q) x where
-  type PP (p <=~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CLe p q))
-
-data p <~ q
-infix 4 <~
-
-instance P (CmpI 'CLt p q) x => P (p <~ q) x where
-  type PP (p <~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CLt p q))
-
-data p /=~ q
-infix 4 /=~
-
-instance P (CmpI 'CNe p q) x => P (p /=~ q) x where
-  type PP (p /=~ q) x = Bool
-  eval _ = evalBool (Proxy @(CmpI 'CNe p q))
-
-
-class GetBinOp (k :: BinOp) where
-  getBinOp :: (Num a, a ~ b) => (String, a -> b -> a)
-
-instance GetBinOp 'BMult where
-  getBinOp = ("*",(*))
-instance GetBinOp 'BSub where
-  getBinOp = ("-",(-))
-instance GetBinOp 'BAdd where
-  getBinOp = ("+",(+))
-
--- | addition, multiplication and subtraction
---
--- >>> pz @(Fst Id * Snd Id) (13,5)
--- PresentT 65
---
--- >>> pz @(Fst Id + 4 * Length (Snd Id) - 4) (3,"hello")
--- PresentT 19
---
-data Bin (op :: BinOp) p q
-
-instance (GetBinOp op
-        , PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Num (PP p a)
-        ) => P (Bin op p q) a where
-  type PP (Bin op p q) a = PP p a
-  eval _ opts a = do
-    let (s,f) = getBinOp @op
-    lr <- runPQ s (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = p `f` q
-        in mkNode opts (PresentT d) (showL opts p <> " " <> s <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
-
--- | fractional division
---
--- >>> pz @(Fst Id / Snd Id) (13,2)
--- PresentT 6.5
---
--- >>> pz @(ToRational 13 / Id) 0
--- FailT "(/) zero denominator"
---
--- >>> pz @(12 % 7 / 14 % 5 + Id) 12.4
--- PresentT (3188 % 245)
---
-data p / q
-infixl 7 /
-
-instance (PP p a ~ PP q a
-        , Eq (PP q a)
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Fractional (PP p a)
-        ) => P (p / q) a where
-  type PP (p / q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "(/)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq)
-         | q == 0 -> let msg1 = msg0 <> " zero denominator"
-                     in mkNode opts (FailT msg1) "" [hh pp, hh qq]
-         | otherwise ->
-            let d = p / q
-            in mkNode opts (PresentT d) (showL opts p <> " / " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
-
--- | creates a 'Rational' value
---
--- >>> pz @(Id < 21 % 5) (-3.1)
--- TrueT
---
--- >>> pz @(Id < 21 % 5) 4.5
--- FalseT
---
--- >>> pz @(Fst Id % Snd Id) (13,2)
--- PresentT (13 % 2)
---
--- >>> pz @(13 % Id) 0
--- FailT "(%) zero denominator"
---
--- >>> pz @(4 % 3 + 5 % 7) "asfd"
--- PresentT (43 % 21)
---
--- >>> pz @(4 -% 7 * 5 -% 3) "asfd"
--- PresentT (20 % 21)
---
--- >>> pz @(Negate (14 % 3)) ()
--- PresentT ((-14) % 3)
---
--- >>> pz @(14 % 3) ()
--- PresentT (14 % 3)
---
--- >>> pz @(Negate (14 % 3) ==! FromIntegral _ (Negate 5)) ()
--- PresentT GT
---
--- >>> pz @(14 -% 3 ==! 5 -% 1) "aa"
--- PresentT GT
---
--- >>> pz @(Negate (14 % 3) ==! Negate 5 % 2) ()
--- PresentT LT
---
--- >>> pz @(14 -% 3 * 5 -% 1) ()
--- PresentT (70 % 3)
---
--- >>> pz @(14 % 3 ==! 5 % 1) ()
--- PresentT LT
---
--- >>> pz @(15 % 3 / 4 % 2) ()
--- PresentT (5 % 2)
---
-data p % q
-infixl 8 %
-
-instance (Integral (PP p x)
-        , Integral (PP q x)
-        , Eq (PP q x)
-        , P p x
-        , P q x
-        , Show (PP p x)
-        , Show (PP q x)
-        ) => P (p % q) x where
-  type PP (p % q) x = Rational
-  eval _ opts x = do
-    let msg0 = "(%)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq)
-         | q == 0 -> let msg1 = msg0 <> " zero denominator"
-                     in mkNode opts (FailT msg1) "" [hh pp, hh qq]
-         | otherwise ->
-            let d = fromIntegral p % fromIntegral q
-                zz= if numerator d == fromIntegral p && denominator d == fromIntegral q then ""
-                    else litVerbose opts " | " (show p <> " % " <> show q)
-            in mkNode opts (PresentT d) (showL opts d <> zz) [hh pp, hh qq]
-
-data p -% q -- = Negate (p % q)
-infixl 8 -%
-type NegateRatioT p q = Negate (p % q)
-
-instance P (NegateRatioT p q) x => P (p -% q) x where
-  type PP (p -% q) x = PP (NegateRatioT p q) x
-  eval _ = eval (Proxy @(NegateRatioT p q))
-
-
--- | similar to 'negate'
---
--- >>> pz @(Negate Id) 14
--- PresentT (-14)
---
--- >>> pz @(Negate (Fst Id * Snd Id)) (14,3)
--- PresentT (-42)
---
--- >>> pz @(Negate (15 -% 4)) "abc"
--- PresentT (15 % 4)
---
--- >>> pz @(Negate (15 % 3)) ()
--- PresentT ((-5) % 1)
---
--- >>> pz @(Negate (Fst Id % Snd Id)) (14,3)
--- PresentT ((-14) % 3)
---
-data Negate p
-
-instance ( Show (PP p x)
-         , Num (PP p x)
-         , P p x
-         ) => P (Negate p) x where
-  type PP (Negate p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Negate"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = negate p
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
-
--- | similar to 'abs'
---
--- >>> pz @(Abs Id) (-14)
--- PresentT 14
---
--- >>> pz @(Abs (Snd Id)) ("xx",14)
--- PresentT 14
---
--- >>> pz @(Abs Id) 0
--- PresentT 0
---
--- >>> pz @(Abs (Negate 44)) "aaa"
--- PresentT 44
---
-data Abs p
-
-instance ( Show (PP p x)
-         , Num (PP p x)
-         , P p x
-         ) => P (Abs p) x where
-  type PP (Abs p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Abs"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = abs p
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
-
-
--- | similar to 'signum'
---
--- >>> pz @(Signum Id) (-14)
--- PresentT (-1)
---
--- >>> pz @(Signum Id) 14
--- PresentT 1
---
--- >>> pz @(Signum Id) 0
--- PresentT 0
---
-data Signum p
-
-instance ( Show (PP p x)
-         , Num (PP p x)
-         , P p x
-         ) => P (Signum p) x where
-  type PP (Signum p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Signum"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = signum p
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
--- | unwraps a value (see '_Wrapped'')
---
--- >>> pz @(Unwrap Id) (SG.Sum (-13))
--- PresentT (-13)
---
-data Unwrap p
-
-instance (PP p x ~ s
-        , P p x
-        , Show s
-        , Show (Unwrapped s)
-        , Wrapped s
-        ) => P (Unwrap p) x where
-  type PP (Unwrap p) x = Unwrapped (PP p x)
-  eval _ opts x = do
-    let msg0 = "Unwrap"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = p ^. _Wrapped'
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
--- | wraps a value (see '_Wrapped'' and '_Unwrapped'')
---
--- >>> pz @(Wrap (SG.Sum _) Id) (-13)
--- PresentT (Sum {getSum = -13})
---
--- >>> pz @(Wrap SG.Any (Ge 4)) 13
--- PresentT (Any {getAny = True})
---
--- >>> pz @(Wrap (NonEmpty _) (Uncons >> 'Just Id)) "abcd"
--- PresentT ('a' :| "bcd")
---
-data Wrap' t p
-
-instance (Show (PP p x)
-        , P p x
-        , Unwrapped (PP s x) ~ PP p x
-        , Wrapped (PP s x)
-        , Show (PP s x)
-        ) => P (Wrap' s p) x where
-  type PP (Wrap' s p) x = PP s x
-  eval _ opts x = do
-    let msg0 = "Wrap"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = p ^. _Unwrapped'
-        in mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
-data Wrap (t :: Type) p
-type WrapT (t :: Type) p = Wrap' (Hole t) p
-
-instance P (WrapT t p) x => P (Wrap t p) x where
-  type PP (Wrap t p) x = PP (WrapT t p) x
-  eval _ = eval (Proxy @(WrapT t p))
--- | similar to 'coerce'
---
--- >>> pz @(Coerce (SG.Sum Integer)) (Identity (-13))
--- PresentT (Sum {getSum = -13})
---
-data Coerce (t :: k)
-
-instance (Show a
-        , Show t
-        , Coercible t a
-        ) => P (Coerce t) a where
-  type PP (Coerce t) a = t
-  eval _ opts a =
-    let msg0 = "Coerce"
-        d = a ^. coerced
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d a) []
-
--- can coerce over a functor: but need to provide type of 'a' and 't' explicitly
-
--- | see 'Coerce': coerce over a functor
---
--- >>> pz @(Coerce2 (SG.Sum Integer)) [Identity (-13), Identity 4, Identity 99]
--- PresentT [Sum {getSum = -13},Sum {getSum = 4},Sum {getSum = 99}]
---
--- >>> pz @(Coerce2 (SG.Sum Integer)) (Just (Identity (-13)))
--- PresentT (Just (Sum {getSum = -13}))
---
--- >>> pz @(Coerce2 (SG.Sum Int)) (Nothing @(Identity Int))
--- PresentT Nothing
---
-data Coerce2 (t :: k)
-instance (Show (f a)
-        , Show (f t)
-        , Coercible t a
-        , Functor f
-        ) => P (Coerce2 t) (f a) where
-  type PP (Coerce2 t) (f a) = f t
-  eval _ opts fa =
-    let msg0 = "Coerce2"
-        d = view coerced <$> fa
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d fa) []
-
--- | lift mempty over a Functor
---
--- >>> pz @(MEmpty2 (SG.Product Int)) [Identity (-13), Identity 4, Identity 99]
--- PresentT [Product {getProduct = 1},Product {getProduct = 1},Product {getProduct = 1}]
---
-data MEmpty2' t
-
-instance (Show (f a)
-        , Show (f (PP t (f a)))
-        , Functor f
-        , Monoid (PP t (f a))
-        ) => P (MEmpty2' t) (f a) where
-  type PP (MEmpty2' t) (f a) = f (PP t (f a))
-  eval _ opts fa =
-    let msg0 = "MEmpty2"
-        b = mempty <$> fa
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b fa) []
-
-data MEmpty2 (t :: Type)
-type MEmpty2T (t :: Type) = MEmpty2' (Hole t)
-
-instance P (MEmpty2T t) x => P (MEmpty2 t) x where
-  type PP (MEmpty2 t) x = PP (MEmpty2T t) x
-  eval _ = eval (Proxy @(MEmpty2T t))
-
--- | lift pure over a Functor
---
--- >>> pz @(Pure2 (Either String)) [1,2,4]
--- PresentT [Right 1,Right 2,Right 4]
---
-data Pure2 (t :: Type -> Type)
-
-instance (Show (f (t a))
-        , Show (f a)
-        , Applicative t
-        , Functor f
-        ) => P (Pure2 t) (f a) where
-  type PP (Pure2 t) (f a) = f (t a)
-  eval _ opts fa =
-    let msg0 = "Pure2"
-        b = fmap pure fa
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b fa) []
-
--- | similar to 'reverse'
---
--- >>> pz @Reverse [1,2,4]
--- PresentT [4,2,1]
---
--- >>> pz @Reverse "AbcDeF"
--- PresentT "FeDcbA"
---
-data Reverse
-
-instance ( Show a
-         , as ~ [a]
-         ) => P Reverse as where
-  type PP Reverse as = as
-  eval _ opts as =
-    let msg0 = "Reverse"
-        d = reverse as
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d as) []
-
--- | reverses using 'reversing'
---
--- >>> pz @ReverseL (T.pack "AbcDeF")
--- PresentT "FeDcbA"
---
--- >>> pz @ReverseL ("AbcDeF" :: String)
--- PresentT "FeDcbA"
---
-data ReverseL
-
-instance ( Show t
-         , Reversing t
-         ) => P ReverseL t where
-  type PP ReverseL t = t
-  eval _ opts as =
-    let msg0 = "ReverseL"
-        d = as ^. reversed
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d as) []
-
--- | swaps using 'SwapC'
---
--- >>> pz @Swap (Left 123)
--- PresentT (Right 123)
---
--- >>> pz @Swap (Right 123)
--- PresentT (Left 123)
---
--- >>> pz @Swap (These 'x' 123)
--- PresentT (These 123 'x')
---
--- >>> pz @Swap (This 'x')
--- PresentT (That 'x')
---
--- >>> pz @Swap (That 123)
--- PresentT (This 123)
---
--- >>> pz @Swap (123,'x')
--- PresentT ('x',123)
---
--- >>> pz @Swap (Left "abc")
--- PresentT (Right "abc")
---
--- >>> pz @Swap (Right 123)
--- PresentT (Left 123)
---
-data Swap
-
-class Bifunctor p => SwapC p where -- (p :: Type -> Type -> Type) where
-  swapC :: p a b -> p b a
-instance SwapC Either where
-  swapC (Left a) = Right a
-  swapC (Right a) = Left a
-instance SwapC These where
-  swapC (This a) = That a
-  swapC (That b) = This b
-  swapC (These a b) = These b a
-instance SwapC (,) where
-  swapC (a,b) = (b,a)
-
-instance (Show (p a b)
-        , SwapC p
-        , Show (p b a)
-        ) => P Swap (p a b) where
-  type PP Swap (p a b) = p b a
-  eval _ opts pabx =
-    let msg0 = "Swap"
-        d = swapC pabx
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabx) []
-
--- | assoc using 'AssocC'
---
--- >>> pz @Assoc (This (These 123 'x'))
--- PresentT (These 123 (This 'x'))
---
--- >>> pz @Assoc ((99,'a'),True)
--- PresentT (99,('a',True))
---
--- >>> pz @Assoc ((99,'a'),True)
--- PresentT (99,('a',True))
---
--- >>> pz @Assoc (Right "Abc" :: Either (Either () ()) String)
--- PresentT (Right (Right "Abc"))
---
--- >>> pz @Assoc (Left (Left 'x'))
--- PresentT (Left 'x')
---
-data Assoc
-
-class AssocC p where
-  assoc :: p (p a b) c -> p a (p b c)
-  unassoc :: p a (p b c) -> p (p a b) c
-instance AssocC Either where
-  assoc (Left (Left a)) = Left a
-  assoc (Left (Right b)) = Right (Left b)
-  assoc (Right b) = Right (Right b)
-  unassoc (Left a) = Left (Left a)
-  unassoc (Right (Left b)) = Left (Right b)
-  unassoc (Right (Right b)) = Right b
-instance AssocC These where
-  assoc (This (This a)) = This a
-  assoc (This (That b)) = That (This b)
-  assoc (That b) = That (That b)
-  assoc (These (This a) c) = These a (That c)
-  assoc (These (That b) c) = That (These b c)
-  assoc (These (These a b) c) = These a (These b c)
-  assoc (This (These a b)) = These a (This b)
-  unassoc (This a) = This (This a)
-  unassoc (That (This b)) = This (That b)
-  unassoc (That (That b)) = That b
-  unassoc (These a (That c)) = These (This a) c
-  unassoc (That (These b c)) = These (That b) c
-  unassoc (These a (These b c)) = These (These a b) c
-  unassoc (These a (This b)) = This (These a b)
-
--- copied from Data.These
-partitionThese :: [These a b] -> ([a], [b], [(a, b)])
-partitionThese [] = ([], [], [])
-partitionThese (t:ts) = case t of
-    This x    -> (x : xs,     ys,         xys)
-    That y    -> (    xs, y : ys,         xys)
-    These x y -> (    xs,     ys, (x,y) : xys)
-  where
-    ~(xs,ys,xys) = partitionThese ts
-
-instance AssocC (,) where
-  assoc ((a,b),c) = (a,(b,c))
-  unassoc (a,(b,c)) = ((a,b),c)
-
-instance (Show (p (p a b) c)
-        , Show (p a (p b c))
-        , AssocC p
-        ) => P Assoc (p (p a b) c) where
-  type PP Assoc (p (p a b) c) = p a (p b c)
-  eval _ opts pabc =
-    let msg0 = "Assoc"
-        d = assoc pabc
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabc) []
-
--- | unassoc using 'AssocC'
---
--- >>> pz @Unassoc (These 123 (This 'x'))
--- PresentT (This (These 123 'x'))
---
--- >>> pz @Unassoc (99,('a',True))
--- PresentT ((99,'a'),True)
---
--- >>> pz @Unassoc (This 10 :: These Int (These Bool ()))
--- PresentT (This (This 10))
---
--- >>> pz @Unassoc (Right (Right 123))
--- PresentT (Right 123)
---
--- >>> pz @Unassoc (Left 'x' :: Either Char (Either Bool Double))
--- PresentT (Left (Left 'x'))
---
-data Unassoc
-
-instance (Show (p (p a b) c)
-        , Show (p a (p b c))
-        , AssocC p
-        ) => P Unassoc (p a (p b c)) where
-  type PP Unassoc (p a (p b c)) = p (p a b) c
-  eval _ opts pabc =
-    let msg0 = "Unassoc"
-        d = unassoc pabc
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d pabc) []
-
--- | bounded 'succ' function
---
--- >>> pz @(SuccB' Id) (13 :: Int)
--- PresentT 14
---
--- >>> pz @(SuccB' Id) LT
--- PresentT EQ
---
--- >>> pz @(SuccB 'LT Id) GT
--- PresentT LT
---
--- >>> pz @(SuccB' Id) GT
--- FailT "Succ bounded"
---
-instance (PP q x ~ a
-        , P q x
-        , P p (Proxy a)
-        , PP p (Proxy a) ~ a
-        , Show a
-        , Eq a
-        , Bounded a
-        , Enum a
-        ) => P (SuccB p q) x where
-  type PP (SuccB p q) x = PP q x
-  eval _ opts x = do
-    let msg0 = "SuccB"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case succMay q of
-          Nothing -> do
-             let msg1 = msg0 <> " out of range"
-             pp <- eval (Proxy @p) opts (Proxy @a)
-             pure $ case getValueLR opts msg1 pp [hh qq] of
-               Left e -> e
-               Right _ -> mkNode opts (_tBool pp) msg1 [hh qq, hh pp]
-          Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n q) [hh qq]
-
-data SuccB p q
-
-data SuccB' q
-type SuccBT' q = SuccB (Failp "Succ bounded") q
-
-instance P (SuccBT' q) x => P (SuccB' q) x where
-  type PP (SuccB' q) x = PP (SuccBT' q) x
-  eval _ = eval (Proxy @(SuccBT' q))
-
--- | bounded 'pred' function
---
--- >>> pz @(PredB' Id) (13 :: Int)
--- PresentT 12
---
--- >>> pz @(PredB' Id) LT
--- FailT "Pred bounded"
---
-data PredB' q
-type PredBT' q = PredB (Failp "Pred bounded") q
-
-instance (PP q x ~ a
-        , P q x
-        , P p (Proxy a)
-        , PP p (Proxy a) ~ a
-        , Show a
-        , Eq a
-        , Bounded a
-        , Enum a
-        ) => P (PredB p q) x where
-  type PP (PredB p q) x = PP q x
-  eval _ opts x = do
-    let msg0 = "PredB"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case predMay q of
-          Nothing -> do
-             let msg1 = msg0 <> " out of range"
-             pp <- eval (Proxy @p) opts (Proxy @a)
-             pure $ case getValueLR opts msg1 pp [hh qq] of
-               Left e -> e
-               Right _ -> mkNode opts (_tBool pp) msg1 [hh qq, hh pp]
-          Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n q) [hh qq]
-
-
--- | unbounded 'succ' function
---
--- >>> pz @(Succ Id) 13
--- PresentT 14
---
--- >>> pz @(Succ Id) LT
--- PresentT EQ
---
--- >>> pz @(Succ Id) GT
--- FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument"
---
-data Succ p
-
-instance (Show a
-        , Enum a
-        , PP p x ~ a
-        , P p x
-        ) => P (Succ p) x where
-  type PP (Succ p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Succ"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        lr <- catchit @_ @E.SomeException (succ p)
-        pure $ case lr of
-          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (" " <> showL opts p) [hh pp]
-          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
-
-
--- | unbounded 'pred' function
---
--- >>> pz @(Pred Id) 13
--- PresentT 12
---
--- >>> pz @(Pred Id) LT
--- FailT "Pred IO e=Prelude.Enum.Ordering.pred: bad argument"
---
-data Pred p
-
-instance (Show a
-        , Enum a
-        , PP p x ~ a
-        , P p x
-        ) => P (Pred p) x where
-  type PP (Pred p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Pred"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        lr <- catchit @_ @E.SomeException (pred p)
-        pure $ case lr of
-          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (" " <> showL opts p) [hh pp]
-          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
-
-data PredB p q
-
-instance P (PredBT' q) x => P (PredB' q) x where
-  type PP (PredB' q) x = PP (PredBT' q) x
-  eval _ = eval (Proxy @(PredBT' q))
-
-
--- | 'fromEnum' function
---
--- >>> pz @(FromEnum Id) 'x'
--- PresentT 120
---
-data FromEnum p
-
-instance (Show a
-        , Enum a
-        , PP p x ~ a
-        , P p x
-        ) => P (FromEnum p) x where
-  type PP (FromEnum p) x = Int
-  eval _ opts x = do
-    let msg0 = "FromEnum"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let n = fromEnum p
-        in mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
-
--- | unsafe 'toEnum' function
---
--- >>> pz @(ToEnum Char Id) 120
--- PresentT 'x'
-data ToEnum' t p
-
-instance (PP p x ~ a
-        , P p x
-        , Show a
-        , Enum (PP t x)
-        , Show (PP t x)
-        , Integral a
-        ) => P (ToEnum' t p) x where
-  type PP (ToEnum' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "ToEnum"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        lr <- catchit @_ @E.SomeException (toEnum $! fromIntegral p)
-        pure $ case lr of
-          Left e -> mkNode opts (FailT (msg0 <> " " <> e)) (" " <> showL opts p) [hh pp]
-          Right n -> mkNode opts (PresentT n) (show01 opts msg0 n p) [hh pp]
-
-data ToEnum (t :: Type) p
-type ToEnumT (t :: Type) p = ToEnum' (Hole t) p
-
-instance P (ToEnumT t p) x => P (ToEnum t p) x where
-  type PP (ToEnum t p) x = PP (ToEnumT t p) x
-  eval _ = eval (Proxy @(ToEnumT t p))
--- | bounded 'toEnum' function
---
--- >>> pz @(ToEnumBDef Ordering LT) 2
--- PresentT GT
---
--- >>> pz @(ToEnumBDef Ordering LT) 6
--- PresentT LT
---
--- >>> pz @(ToEnumBFail Ordering) 6
--- FailT "ToEnum bounded"
---
-data ToEnumBDef' t def
-
-instance (P def (Proxy (PP t a))
-        , PP def (Proxy (PP t a)) ~ PP t a
-        , Show a
-        , Show (PP t a)
-        , Bounded (PP t a)
-        , Enum (PP t a)
-        , Integral a
-        ) => P (ToEnumBDef' t def) a where
-  type PP (ToEnumBDef' t def) a = PP t a
-  eval _ opts a = do
-    let msg0 = "ToEnumBDef"
-    case toEnumMay $ fromIntegral a of
-      Nothing -> do
-         let msg1 = msg0 <> " out of range"
-         pp <- eval (Proxy @def) opts (Proxy @(PP t a))
-         pure $ case getValueLR opts msg1 pp [] of
-           Left e -> e
-           Right _ -> mkNode opts (_tBool pp) msg1 [hh pp]
-      Just n -> pure $ mkNode opts (PresentT n) (show01 opts msg0 n a) []
-
-data ToEnumBDef (t :: Type) def
-type ToEnumBDefT (t :: Type) def = ToEnumBDef' (Hole t) def
-
-instance P (ToEnumBDefT t def) x => P (ToEnumBDef t def) x where
-  type PP (ToEnumBDef t def) x = PP (ToEnumBDefT t def) x
-  eval _ = eval (Proxy @(ToEnumBDefT t def))
-
-data ToEnumBFail (t :: Type)
-type ToEnumBFailT (t :: Type) = ToEnumBDef' (Hole t) (Failp "ToEnum bounded")
-
-instance P (ToEnumBFailT t) x => P (ToEnumBFail t) x where
-  type PP (ToEnumBFail t) x = PP (ToEnumBFailT t) x
-  eval _ = eval (Proxy @(ToEnumBFailT t))
-
--- | a predicate on prime numbers
---
--- >>> pz @(Prime Id) 2
--- TrueT
---
--- >>> pz @(Map '(Id,Prime Id) Id) [0..12]
--- PresentT [(0,False),(1,False),(2,True),(3,True),(4,False),(5,True),(6,False),(7,True),(8,False),(9,False),(10,False),(11,True),(12,False)]
---
-data Prime p
-
-instance (PP p x ~ a
-        , P p x
-        , Show a
-        , Integral a
-        ) => P (Prime p) x where
-  type PP (Prime p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Prime"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = p > 1 && isPrime (fromIntegral p)
-        in mkNodeB opts b (msg0 <> showVerbose opts " | " p) [hh pp]
-
--- | get the next prime number
---
--- >>> pz @(PrimeNext Id) 6
--- PresentT 7
---
--- >>> pz @(IterateN 4 (PrimeNext Id)) 3
--- PresentT [3,5,7,11]
---
-data PrimeNext p
-
-instance (PP p x ~ a
-        , P p x
-        , Show a
-        , Integral a
-        ) => P (PrimeNext p) x where
-  type PP (PrimeNext p) x = Int
-  eval _ opts x = do
-    let msg0 = "PrimeNext"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let ret = head $ dropWhile (not . isPrime) [max 0 (fromIntegral p + 1) ..]
-        in mkNode opts (PresentT ret) (msg0 <> showVerbose opts " | " p) [hh pp]
-
--- empty lists at the type level wont work here
-
--- | filters a list \'q\' keeping or removing those elements in \'p\'
---
--- >>> pz @(Keep '[5] '[1,5,5,2,5,2]) ()
--- PresentT [5,5,5]
---
--- >>> pz @(Keep '[0,1,1,5] '[1,5,5,2,5,2]) ()
--- PresentT [1,5,5,5]
---
--- >>> pz @(Remove '[5] '[1,5,5,2,5,2]) ()
--- PresentT [1,2,2]
---
--- >>> pz @(Remove '[0,1,1,5] '[1,5,5,2,5,2]) ()
--- PresentT [2,2]
---
--- >>> pz @(Remove '[99] '[1,5,5,2,5,2]) ()
--- PresentT [1,5,5,2,5,2]
---
--- >>> pz @(Remove '[99,91] '[1,5,5,2,5,2]) ()
--- PresentT [1,5,5,2,5,2]
---
--- >>> pz @(Remove Id '[1,5,5,2,5,2]) []
--- PresentT [1,5,5,2,5,2]
---
--- >>> pz @(Remove '[] '[1,5,5,2,5,2]) 44 -- works if you make this a number!
--- PresentT [1,5,5,2,5,2]
---
-data KeepImpl (keep :: Bool) p q
-
-instance (GetBool keep
-        , Eq a
-        , Show a
-        , P p x
-        , P q x
-        , PP p x ~ PP q x
-        , PP q x ~ [a]
-        ) => P (KeepImpl keep p q) x where
-  type PP (KeepImpl keep p q) x = PP q x
-  eval _ opts x = do
-    let msg0 = if keep then "Keep" else "Remove"
-        keep = getBool @keep
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let ret = filter (bool not id keep . (`elem` p)) q
-        in mkNode opts (PresentT ret) (show01' opts msg0 ret "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
-data Keep p q
-type KeepT p q = KeepImpl 'True p q
-
-instance P (KeepT p q) x => P (Keep p q) x where
-  type PP (Keep p q) x = PP (KeepT p q) x
-  eval _ = eval (Proxy @(KeepT p q))
-
-data Remove p q
-type RemoveT p q = KeepImpl 'False p q
-
-instance P (RemoveT p q) x => P (Remove p q) x where
-  type PP (Remove p q) x = PP (RemoveT p q) x
-  eval _ = eval (Proxy @(RemoveT p q))
-
--- | 'elem' function
---
--- >>> pz @(Elem (Fst Id) (Snd Id)) ('x',"abcdxy")
--- TrueT
---
--- >>> pz @(Elem (Fst Id) (Snd Id)) ('z',"abcdxy")
--- FalseT
---
-data Elem p q
-
-instance ([PP p a] ~ PP q a
-         , P p a
-         , P q a
-         , Show (PP p a)
-         , Eq (PP p a)
-         ) => P (Elem p q) a where
-  type PP (Elem p q) a = Bool
-  eval _ opts a = do
-    let msg0 = "Elem"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = p `elem` q
-        in mkNodeB opts b (showL opts p <> " `elem` " <> showL opts q) [hh pp, hh qq]
-
---type Head' p = HeadFail "Head(empty)" p
---type Tail' p = TailFail "Tail(empty)" p
---type Last p = LastFail "Last(empty)" p
---type Init' p = InitFail "Init(empty)" p
-
--- | similar to fmap fst
---
--- >>> pz @FMapFst (Just (13,"Asf"))
--- PresentT (Just 13)
---
--- to make this work we grab the fst or snd out of the Maybe so it is a head or not/ is a tail or not etc!
--- we still have access to the whole original list so we dont lose anything!
-data FMapFst
-
-instance Functor f => P FMapFst (f (a,x)) where
-  type PP FMapFst (f (a,x)) = f a
-  eval _ opts mb = pure $ mkNode opts (PresentT (fst <$> mb)) "FMapFst" []
-
--- | similar to fmap snd
---
--- >>> pz @FMapSnd (Just ("asf",13))
--- PresentT (Just 13)
---
-data FMapSnd
-
-instance Functor f => P FMapSnd (f (x,a)) where
-  type PP FMapSnd (f (x,a)) = f a
-  eval _ opts mb = pure $ mkNode opts (PresentT (snd <$> mb)) "FMapSnd" []
-
--- | takes the head or default of a list-like object
---
--- see 'ConsT' for other supported types eg 'Seq.Seq'
---
--- >>> pz @(HeadDef 444 Id) []
--- PresentT 444
---
--- >>> pz @(HeadDef 444 Id) [1..5]
--- PresentT 1
---
--- >>> pz @(HeadDef 444 Id) [1..5]
--- PresentT 1
---
--- >>> pz @(HeadDef (Char1 "w") Id) (Seq.fromList "abcdef")
--- PresentT 'a'
---
--- >>> pz @(HeadDef (Char1 "w") Id) Seq.empty
--- PresentT 'w'
---
--- >>> :set -XFlexibleContexts
--- >>> pz @(HeadDef (MEmptyT _) Id) ([] :: [SG.Sum Int])
--- PresentT (Sum {getSum = 0})
---
--- >>> pz @(HeadDef (MEmptyT String) '[ "abc","def","asdfadf" ]) ()
--- PresentT "abc"
---
--- >>> pz @(HeadDef (MEmptyT _) (Snd Id)) (123,[ "abc","def","asdfadf" ])
--- PresentT "abc"
---
--- >>> pz @(HeadDef (MEmptyT _) (Snd Id)) (123,[])
--- PresentT ()
---
-data HeadDef p q
-type HeadDefT p q = JustDef p (q >> Uncons >> FMapFst)
-
-instance P (HeadDefT p q) x => P (HeadDef p q) x where
-  type PP (HeadDef p q) x = PP (HeadDefT p q) x
-  eval _ = eval (Proxy @(HeadDefT p q))
-
-
--- | takes the head of a list or fail
---
--- see 'ConsT' for other supported types eg 'Seq.Seq'
---
--- >>> pz @(HeadFail "dude" Id) [ "abc","def","asdfadf" ]
--- PresentT "abc"
---
--- >>> pz @(HeadFail "empty list" Id) []
--- FailT "empty list"
---
-data HeadFail msg q
-type HeadFailT msg q = JustFail msg (q >> Uncons >> FMapFst)
-
-instance P (HeadFailT msg q) x => P (HeadFail msg q) x where
-  type PP (HeadFail msg q) x = PP (HeadFailT msg q) x
-  eval _ = eval (Proxy @(HeadFailT msg q))
-
-data TailDef p q
-type TailDefT p q = JustDef p (q >> Uncons >> FMapSnd)
-
-instance P (TailDefT p q) x => P (TailDef p q) x where
-  type PP (TailDef p q) x = PP (TailDefT p q) x
-  eval _ = eval (Proxy @(TailDefT p q))
-
-
-data TailFail msg q
-type TailFailT msg q = JustFail msg (q >> Uncons >> FMapSnd)
-
-instance P (TailFailT msg q) x => P (TailFail msg q) x where
-  type PP (TailFail msg q) x = PP (TailFailT msg q) x
-  eval _ = eval (Proxy @(TailFailT msg q))
-
-
-data LastDef p q
-type LastDefT p q = JustDef p (q >> Unsnoc >> FMapSnd)
-
-instance P (LastDefT p q) x => P (LastDef p q) x where
-  type PP (LastDef p q) x = PP (LastDefT p q) x
-  eval _ = eval (Proxy @(LastDefT p q))
-
-data LastFail msg q
-type LastFailT msg q = JustFail msg (q >> Unsnoc >> FMapSnd)
-
-instance P (LastFailT msg q) x => P (LastFail msg q) x where
-  type PP (LastFail msg q) x = PP (LastFailT msg q) x
-  eval _ = eval (Proxy @(LastFailT msg q))
-
-data InitDef p q
-type InitDefT p q = JustDef p (q >> Unsnoc >> FMapFst)
-
-instance P (InitDefT p q) x => P (InitDef p q) x where
-  type PP (InitDef p q) x = PP (InitDefT p q) x
-  eval _ = eval (Proxy @(InitDefT p q))
-
-data InitFail msg q
-type InitFailT msg q = JustFail msg (q >> Unsnoc >> FMapFst)
-
-instance P (InitFailT msg q) x => P (InitFail msg q) x where
-  type PP (InitFail msg q) x = PP (InitFailT msg q) x
-  eval _ = eval (Proxy @(InitFailT msg q))
-
-data LookupDef' v w p q
-type LookupDefT' v w p q = JustDef p (q >> Lookup v w)
-
-instance P (LookupDefT' v w p q) x => P (LookupDef' v w p q) x where
-  type PP (LookupDef' v w p q) x = PP (LookupDefT' v w p q) x
-  eval _ = eval (Proxy @(LookupDefT' v w p q))
-
-data LookupFail' msg v w q
-type LookupFailT' msg v w q = JustFail msg (q >> Lookup v w)
-
-instance P (LookupFailT' msg v w q) x => P (LookupFail' msg v w q) x where
-  type PP (LookupFail' msg v w q) x = PP (LookupFailT' msg v w q) x
-  eval _ = eval (Proxy @(LookupFailT' msg v w q))
-
-data LookupDef v w p
-type LookupDefT v w p = LookupDef' v w p I
-
-instance P (LookupDefT v w p) x => P (LookupDef v w p) x where
-  type PP (LookupDef v w p) x = PP (LookupDefT v w p) x
-  eval _ = eval (Proxy @(LookupDefT v w p))
-
-data LookupFail msg v w
-type LookupFailT msg v w = LookupFail' msg v w I
-
-instance P (LookupFailT msg v w) x => P (LookupFail msg v w) x where
-  type PP (LookupFail msg v w) x = PP (LookupFailT msg v w) x
-  eval _ = eval (Proxy @(LookupFailT msg v w))
-
---type Just'  p = JustFail  "expected Just" p
-data Left' p
-type LeftT' p = LeftFail "expected Left"  p
-
-instance P (LeftT' p) x => P (Left' p) x where
-  type PP (Left' p) x = PP (LeftT' p) x
-  eval _ = eval (Proxy @(LeftT' p))
-
-data Right' p
-type RightT' p = RightFail "expected Right" p
-
-instance P (RightT' p) x => P (Right' p) x where
-  type PP (Right' p) x = PP (RightT' p) x
-  eval _ = eval (Proxy @(RightT' p))
-
-data This'  p
-type ThisT'  p = ThisFail  "expected This"  p
-
-instance P (ThisT' p) x => P (This' p) x where
-  type PP (This' p) x = PP (ThisT' p) x
-  eval _ = eval (Proxy @(ThisT' p))
-
-data That'  p
-type ThatT'  p = ThatFail  "expected That"  p
-
-instance P (ThatT' p) x => P (That' p) x where
-  type PP (That' p) x = PP (ThatT' p) x
-  eval _ = eval (Proxy @(ThatT' p))
-
-data These' p
-type TheseT' p = TheseFail "expected These" p
-
-instance P (TheseT' p) x => P (These' p) x where
-  type PP (These' p) x = PP (TheseT' p) x
-  eval _ = eval (Proxy @(TheseT' p))
-
-
--- | similar to 'Control.Arrow.|||' but additionally gives \'p\' and \'q\' the original input
---
--- >>> pz @(EitherX (ShowP (Fst (Fst Id) + Snd Id)) (ShowP Id) (Snd Id)) (9,Left 123)
--- PresentT "132"
---
--- >>> pz @(EitherX (ShowP (Fst (Fst Id) + Snd Id)) (ShowP Id) (Snd Id)) (9,Right 'x')
--- PresentT "((9,Right 'x'),'x')"
---
--- >>> pz @(EitherX (ShowP Id) (ShowP (Second (Succ Id))) (Snd Id)) (9,Right 'x')
--- PresentT "((9,Right 'x'),'y')"
---
-data EitherX p q r
-instance (P r x
-        , P p (x,a)
-        , P q (x,b)
-        , PP r x ~ Either a b
-        , PP p (x,a) ~ c
-        , PP q (x,b) ~ c
-        ) => P (EitherX p q r) x where
-  type PP (EitherX p q r) x = EitherXT (PP r x) x p
-  eval _ opts x = do
-    let msg0 = "EitherX"
-    rr <- eval (Proxy @r) opts x
-    case getValueLR opts msg0 rr [] of
-      Left e -> pure e
-      Right (Left a) -> do
-        let msg1 = msg0 <> "(Left)"
-        pp <- eval (Proxy @p) opts (x,a)
-        pure $ case getValueLR opts msg1 pp [hh rr] of
-          Left e -> e
-          Right _ -> mkNode opts (_tBool pp) msg1 [hh rr, hh pp]
-      Right (Right b) -> do
-        let msg1 = msg0 <> "(Right)"
-        qq <- eval (Proxy @q) opts (x,b)
-        pure $ case getValueLR opts msg1 qq [hh rr] of
-          Left e -> e
-          Right _ -> mkNode opts (_tBool qq) msg1 [hh rr, hh qq]
-
-type family EitherXT lr x p where
-  EitherXT (Either a b) x p = PP p (x,a)
-  EitherXT o _ _ = GL.TypeError (
-      'GL.Text "EitherXT: expected 'Either a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
--- | similar to 'Data.These.mergeTheseWith' but additionally provides \'p\', '\q'\ and \'r\' the original input as the first element in the tuple
---
--- >>> pz @(TheseX ((Fst (Fst Id) + Snd Id) >> ShowP Id) (ShowP Id) (Snd (Snd Id)) (Snd Id)) (9,This 123)
--- PresentT "132"
---
--- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (This 123)
--- PresentT (123,"fromthis")
---
--- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (That "fromthat")
--- PresentT (-99,"fromthat")
---
--- >>> pz @(TheseX '(Snd Id,"fromthis") '(Negate 99,Snd Id) (Snd Id) Id) (These 123 "fromthese")
--- PresentT (123,"fromthese")
---
-data TheseX p q r s
-
-instance (P s x
-        , P p (x,a)
-        , P q (x,b)
-        , P r (x,(a,b))
-        , PP s x ~ These a b
-        , PP p (x,a) ~ c
-        , PP q (x,b) ~ c
-        , PP r (x,(a,b)) ~ c
-        ) => P (TheseX p q r s) x where
-  type PP (TheseX p q r s) x = TheseXT (PP s x) x p
-  eval _ opts x = do
-    let msg0 = "TheseX"
-    ss <- eval (Proxy @s) opts x
-    case getValueLR opts msg0 ss [] of
-      Left e -> pure e
-      Right (This a) -> do
-        let msg1 = msg0 <> "(This)"
-        pp <- eval (Proxy @p) opts (x,a)
-        pure $ case getValueLR opts msg1 pp [hh ss] of
-          Left e -> e
-          Right _ -> mkNode opts (_tBool pp) msg1 [hh ss, hh pp]
-      Right (That b) -> do
-        let msg1 = msg0 <> "(That)"
-        qq <- eval (Proxy @q) opts (x,b)
-        pure $ case getValueLR opts msg1 qq [hh ss] of
-          Left e -> e
-          Right _ -> mkNode opts (_tBool qq) msg1 [hh ss, hh qq]
-      Right (These a b) -> do
-        let msg1 = msg0 <> "(These)"
-        rr <- eval (Proxy @r) opts (x,(a,b))
-        pure $ case getValueLR opts msg1 rr [hh ss] of
-          Left e -> e
-          Right _ -> mkNode opts (_tBool rr) msg1 [hh ss, hh rr]
-
-type family TheseXT lr x p where
-  TheseXT (These a b) x p = PP p (x,a)
-
--- | similar to 'maybe'
---
--- provides a Proxy to the result of \'q\' but does not provide the surrounding context
---
--- >>> pz @(MaybeIn "foundnothing" (ShowP (Pred Id))) (Just 20)
--- PresentT "19"
---
--- >>> pz @(MaybeIn "found nothing" (ShowP (Pred Id))) Nothing
--- PresentT "found nothing"
---
-data MaybeIn p q
-
--- tricky: the nothing case is the proxy of PP q a: ie proxy of the final result
-instance (P q a
-        , Show a
-        , Show (PP q a)
-        , PP p (Proxy (PP q a)) ~ PP q a
-        , P p (Proxy (PP q a))
-        ) => P (MaybeIn p q) (Maybe a) where
-  type PP (MaybeIn p q) (Maybe a) = PP q a
-  eval _ opts ma = do
-    let msg0 = "MaybeIn"
-    case ma of
-      Nothing -> do
-        let msg1 = msg0 <> "(Nothing)"
-        pp <- eval (Proxy @p) opts (Proxy @(PP q a))
-        pure $ case getValueLR opts msg1 pp [] of
-          Left e -> e
-          Right b -> mkNode opts (_tBool pp) (msg1 <> " " <> showL opts b <> " | Proxy") [hh pp]
-      Just a -> do
-        let msg1 = msg0 <> "(Just)"
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg1 qq [] of
-          Left e -> e
-          Right b -> mkNode opts (_tBool qq) (show01 opts msg1 b a) [hh qq]
-
--- | similar to 'isJust'
---
--- >>> pz @(IsJust Id) Nothing
--- FalseT
---
--- >>> pz @(IsJust Id) (Just 'a')
--- TrueT
---
-data IsJust p
-
-instance ( P p x
-         , PP p x ~ Maybe a
-         ) => P (IsJust p) x where
-  type PP (IsJust p) x = Bool
-  eval _ opts x = do
-    let msg0 = "IsJust"
-    pp <- eval (Proxy @p) opts x
-    let hhs = [hh pp]
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right (Just _) -> mkNodeB opts True msg0 hhs
-      Right Nothing -> mkNodeB opts False msg0 hhs
-
--- | similar to 'isNothing'
---
--- >>> pz @(IsNothing Id) (Just 123)
--- FalseT
---
--- >>> pz @(IsNothing Id) Nothing
--- TrueT
---
-data IsNothing p
-
-instance ( P p x
-         , PP p x ~ Maybe a
-         ) => P (IsNothing p) x where
-  type PP (IsNothing p) x = Bool
-  eval _ opts x = do
-    let msg0 = "IsNothing"
-    pp <- eval (Proxy @p) opts x
-    let hhs = [hh pp]
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right (Just _) -> mkNodeB opts False msg0 hhs
-      Right Nothing -> mkNodeB opts True msg0 hhs
-
-data MapMaybe p q
-type MapMaybeT p q = ConcatMap (p >> MaybeIn MEmptyP '[Id]) q
-
-instance P (MapMaybeT p q) x => P (MapMaybe p q) x where
-  type PP (MapMaybe p q) x = PP (MapMaybeT p q) x
-  eval _ = eval (Proxy @(MapMaybeT p q))
-
--- | similar to 'Data.Either.catMaybes'
---
--- >>> pl @(CatMaybes Id) [Just 'a',Nothing,Just 'c',Just 'd',Nothing]
--- Present "acd" (Concat "acd" | ["a","","c","d",""])
--- PresentT "acd"
---
-data CatMaybes q
-type CatMaybesT q = MapMaybe Id q
-
-instance P (CatMaybesT q) x => P (CatMaybes q) x where
-  type PP (CatMaybes q) x = PP (CatMaybesT q) x
-  eval _ = eval (Proxy @(CatMaybesT q))
-
--- | similar to 'SG.stimes'
---
--- >>> pz @(STimes 4 Id) (SG.Sum 3)
--- PresentT (Sum {getSum = 12})
---
--- >>> pz @(STimes 4 Id) "ab"
--- PresentT "abababab"
---
-data STimes n p
-instance (P n a
-        , Integral (PP n a)
-        , Semigroup (PP p a)
-        , P p a
-        , Show (PP p a)
-        ) => P (STimes n p) a where
-  type PP (STimes n p) a = PP p a
-  eval _ opts a = do
-    let msg0 = "STimes"
-    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (fromIntegral -> (n::Int),p,pp,qq) ->
-        let msg1 = msg0 <> " " <> showL opts n <> " p=" <> show p
-            b = SG.stimes n p
-            in mkNode opts (PresentT b) (show01' opts msg1 b "n=" n <> showVerbose opts " | " p) [hh pp, hh qq]
-
-
--- | similar to 'pure'
---
--- >>> pz @(Pure Maybe Id) 4
--- PresentT (Just 4)
---
--- >>> pz @(Pure [] Id) 4
--- PresentT [4]
---
--- >>> pz @(Pure (Either String) (Fst Id)) (13,True)
--- PresentT (Right 13)
---
-data Pure (t :: Type -> Type) p
-instance (P p x
-        , Show (PP p x)
-        , Show (t (PP p x))
-        , Applicative t
-        ) => P (Pure t p) x where
-  type PP (Pure t p) x = t (PP p x)
-  eval _ opts x = do
-    let msg0 = "Pure"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right a ->
-        let b = pure a
-        in mkNode opts (PresentT b) (show01 opts msg0 b a) [hh pp]
-
--- type PMEmpty = MEmptyT' 'Proxy  -- lifts 'a' to 'Proxy a' then we can use it with MEmptyP
-
--- | similar to 'mempty'
---
--- >>> pz @(MEmptyT (SG.Sum Int)) ()
--- PresentT (Sum {getSum = 0})
---
--- no Monoid for Maybe a unless a is also a monoid but can use empty!
-data MEmptyT' t
-instance ( Show (PP t a)
-         , Monoid (PP t a)
-         ) => P (MEmptyT' t) a where
-  type PP (MEmptyT' t) a = PP t a
-  eval _ opts _ =
-    let msg0 = "MEmptyT"
-        b = mempty @(PP t a)
-    in pure $ mkNode opts (PresentT b) (msg0 <> " " <> showL opts b) []
-
-data MEmptyT (t :: Type)
-type MEmptyTT (t :: Type) = MEmptyT' (Hole t)
-
-instance P (MEmptyTT t) x => P (MEmptyT t) x where
-  type PP (MEmptyT t) x = PP (MEmptyTT t) x
-  eval _ = eval (Proxy @(MEmptyTT t))
-
-data MEmptyP
-type MEmptyPT = MEmptyT' Unproxy -- expects a proxy: so only some things work with this: eg MaybeIn
-
-instance P MEmptyPT x => P MEmptyP x where
-  type PP MEmptyP x = PP MEmptyPT x
-  eval _ = eval (Proxy @MEmptyPT)
-
--- | similar to 'empty'
---
--- >>> pz @(EmptyT Maybe Id) ()
--- PresentT Nothing
---
--- >>> pz @(EmptyT [] Id) ()
--- PresentT []
---
--- >>> pz @(EmptyT [] (Char1 "x")) (13,True)
--- PresentT ""
---
--- >>> pz @(EmptyT (Either String) (Fst Id)) (13,True)
--- PresentT (Left "")
---
-data EmptyT (t :: Type -> Type) p
-
-instance (P p x
-        , PP p x ~ a
-        , Show (t a)
-        , Show a
-        , Alternative t
-        ) => P (EmptyT t p) x where
-  type PP (EmptyT t p) x = t (PP p x)
-  eval _ opts x = do
-    let msg0 = "EmptyT"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = empty @t
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data MkNothing' t -- works always! MaybeBool is a good alternative and then dont need the extra 't'
-
--- for this to be useful has to have 't' else we end up with tons of problems
-instance P (MkNothing' t) a where
-  type PP (MkNothing' t) a = Maybe (PP t a)
-  eval _ opts _ =
-    let msg0 = "MkNothing"
-    in pure $ mkNode opts (PresentT Nothing) msg0 []
-
-data MkNothing (t :: Type)
-type MkNothingT (t :: Type) = MkNothing' (Hole t)
-
-instance P (MkNothing t) x where
-  type PP (MkNothing t) x = PP (MkNothingT t) x
-  eval _ = eval (Proxy @(MkNothingT t))
-
--- | 'GHC.Maybe.Just' constructor
---
--- >>> pz @(MkJust Id) 44
--- PresentT (Just 44)
---
-data MkJust p
-instance ( PP p x ~ a
-         , P p x
-         , Show a
-         ) => P (MkJust p) x where
-  type PP (MkJust p) x = Maybe (PP p x)
-  eval _ opts x = do
-    let msg0 = "MkJust"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = Just p
-        in mkNode opts (PresentT d) (msg0 <> " Just " <> showL opts p) [hh pp]
-
--- | 'Data.Either.Left' constructor
---
--- >>> pz @(MkLeft _ Id) 44
--- PresentT (Left 44)
---
-data MkLeft' t p
-
-instance ( Show (PP p x)
-         , P p x
-         ) => P (MkLeft' t p) x where
-  type PP (MkLeft' t p) x = Either (PP p x) (PP t x)
-  eval _ opts x = do
-    let msg0 = "MkLeft"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = Left p
-        in mkNode opts (PresentT d) (msg0 <> " Left " <> showL opts p) [hh pp]
-
-data MkLeft (t :: Type) p
-type MkLeftT (t :: Type) p = MkLeft' (Hole t) p
-
-instance P (MkLeftT t p) x => P (MkLeft t p) x where
-  type PP (MkLeft t p) x = PP (MkLeftT t p) x
-  eval _ = eval (Proxy @(MkLeftT t p))
-
--- | 'Data.Either.Right' constructor
---
--- >>> pz @(MkRight _ Id) 44
--- PresentT (Right 44)
---
-data MkRight' t p
-
-instance ( Show (PP p x)
-         , P p x
-         ) => P (MkRight' t p) x where
-  type PP (MkRight' t p) x = Either (PP t x) (PP p x)
-  eval _ opts x = do
-    let msg0 = "MkRight"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = Right p
-        in mkNode opts (PresentT d) (msg0 <> " Right " <> showL opts p) [hh pp]
-
-data MkRight (t :: Type) p
-type MkRightT (t :: Type) p = MkRight' (Hole t) p
-
-instance P (MkRightT t p) x => P (MkRight t p) x where
-  type PP (MkRight t p) x = PP (MkRightT t p) x
-  eval _ = eval (Proxy @(MkRightT t p))
-
--- | 'Data.These.This' constructor
---
--- >>> pz @(MkThis _ Id) 44
--- PresentT (This 44)
---
--- >>> pz @(Proxy Int >> MkThis' Unproxy 10) []
--- PresentT (This 10)
---
-data MkThis' t p
-
-instance ( Show (PP p x)
-         , P p x
-         ) => P (MkThis' t p) x where
-  type PP (MkThis' t p) x = These (PP p x) (PP t x)
-  eval _ opts x = do
-    let msg0 = "MkThis"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = This p
-        in mkNode opts (PresentT d) (msg0 <> " This " <> showL opts p) [hh pp]
-
-data MkThis (t :: Type) p
-type MkThisT (t :: Type) p = MkThis' (Hole t) p
-
-instance P (MkThisT t p) x => P (MkThis t p) x where
-  type PP (MkThis t p) x = PP (MkThisT t p) x
-  eval _ = eval (Proxy @(MkThisT t p))
-
--- | 'Data.These.That' constructor
---
--- >>> pz @(MkThat _ Id) 44
--- PresentT (That 44)
---
-data MkThat' t p
-
-instance ( Show (PP p x)
-         , P p x
-         ) => P (MkThat' t p) x where
-  type PP (MkThat' t p) x = These (PP t x) (PP p x)
-  eval _ opts x = do
-    let msg0 = "MkThat"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = That p
-        in mkNode opts (PresentT d) (msg0 <> " That " <> showL opts p) [hh pp]
-
-data MkThat (t :: Type) p
-type MkThatT (t :: Type) p = MkThat' (Hole t) p
-
-instance P (MkThatT t p) x => P (MkThat t p) x where
-  type PP (MkThat t p) x = PP (MkThatT t p) x
-  eval _ = eval (Proxy @(MkThatT t p))
-
--- type MkThat t p = MkThis t p >> Swap
--- type MkThat' (t :: Type) = Pure (These t) Id -- t has to be a semigroup
-
--- | 'Data.These.These' constructor
---
--- >>> pz @(MkThese (Fst Id) (Snd Id)) (44,'x')
--- PresentT (These 44 'x')
---
-data MkThese p q
-instance (P p a
-        , P q a
-        , Show (PP p a)
-        , Show (PP q a)
-        ) => P (MkThese p q) a where
-  type PP (MkThese p q) a = These (PP p a) (PP q a)
-  eval _ opts a = do
-    let msg0 = "MkThese"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = These p q
-        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts d) [hh pp, hh qq]
-
--- | similar to 'mconcat'
---
--- >>> pz @(MConcat Id) [SG.Sum 44, SG.Sum 12, SG.Sum 3]
--- PresentT (Sum {getSum = 59})
---
--- >>> pz @(Map '(Pure SG.Sum Id, Pure SG.Max Id) Id >> MConcat Id) [7 :: Int,6,1,3,5] -- monoid so need eg Int
--- PresentT (Sum {getSum = 22},Max {getMax = 7})
---
-data MConcat p
-
-instance (PP p x ~ [a]
-        , P p x
-        , Show a
-        , Monoid a
-        ) => P (MConcat p) x where
-  type PP (MConcat p) x = ExtractAFromList (PP p x)
-  eval _ opts x = do
-    let msg0 = "MConcat"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = mconcat p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
--- | similar to 'SG.sconcat'
---
--- >>> pz @(ToNEList >> SConcat Id) [SG.Sum 44, SG.Sum 12, SG.Sum 3]
--- PresentT (Sum {getSum = 59})
---
--- >>> pz @(Map '(Pure SG.Sum Id, Pure SG.Max Id) Id >> ToNEList >> SConcat Id) [7,6,1,3,5]
--- PresentT (Sum {getSum = 22},Max {getMax = 7})
---
-data SConcat p
-
-instance (PP p x ~ NonEmpty a
-        , P p x
-        , Show a
-        , Semigroup a
-        ) => P (SConcat p) x where
-  type PP (SConcat p) x = ExtractAFromTA (PP p x)
-  eval _ opts x = do
-    let msg0 = "SConcat"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = SG.sconcat p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
-data ToNEList
-instance (Show (t a)
-        , Foldable t
-        ) => P ToNEList (t a) where
-  type PP ToNEList (t a) = NonEmpty a
-  eval _ opts as =
-    let msg0 = "ToNEList"
-    in pure $ case toList as of
-         [] -> mkNode opts (FailT "empty list") msg0 []
-         x:xs -> mkNode opts (PresentT (x N.:| xs)) (msg0 <> showVerbose opts " " as) []
-
-
--- | similar to a limited form of 'foldMap'
---
--- >>> pz @(FoldMap (SG.Sum _) Id) [44, 12, 3]
--- PresentT 59
---
--- >>> pz @(FoldMap (SG.Product _) Id) [44, 12, 3]
--- PresentT 1584
---
--- >>> type Ands' p = FoldMap SG.All p
--- >>> pz @(Ands' Id) [True,False,True,True]
--- PresentT False
---
--- >>> pz @(Ands' Id) [True,True,True]
--- PresentT True
---
--- >>> pz @(Ands' Id) []
--- PresentT True
---
--- >>> type Ors' p = FoldMap SG.Any p
--- >>> pz @(Ors' Id) [False,False,False]
--- PresentT False
---
--- >>> pz @(Ors' Id) []
--- PresentT False
---
--- >>> pz @(Ors' Id) [False,False,False,True]
--- PresentT True
---
--- >>> type AllPositive' = FoldMap SG.All (Map Positive Id)
--- >>> pz @AllPositive' [3,1,-5,10,2,3]
--- PresentT False
---
--- >>> type AllNegative' = FoldMap SG.All (Map Negative Id)
--- >>> pz @AllNegative' [-1,-5,-10,-2,-3]
--- PresentT True
---
--- >>> :set -XKindSignatures
--- >>> type Max' (t :: Type) = FoldMap (SG.Max t) Id -- requires t be Bounded for monoid instance
--- >>> pz @(Max' Int) [10,4,5,12,3,4]
--- PresentT 12
---
-data FoldMap (t :: Type) p
-type FoldMapT (t :: Type) p = Map (Wrap t Id) p >> Unwrap (MConcat Id)
-
-instance P (FoldMapT t p) x => P (FoldMap t p) x where
-  type PP (FoldMap t p) x = PP (FoldMapT t p) x
-  eval _ = eval (Proxy @(FoldMapT t p))
-
--- | similar to 'concat'
---
--- >>> pz @(Concat Id) ["abc","D","eF","","G"]
--- PresentT "abcDeFG"
---
--- >>> pz @(Concat (Snd Id)) ('x',["abc","D","eF","","G"])
--- PresentT "abcDeFG"
---
-data Concat p
-
-instance (Show a
-        , Show (t [a])
-        , PP p x ~ t [a]
-        , P p x
-        , Foldable t
-        ) => P (Concat p) x where
-  type PP (Concat p) x = ExtractAFromTA (PP p x)
-  eval _ opts x = do
-    let msg0 = "Concat"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = concat p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) [hh pp]
-
--- | similar to 'cycle' but for a fixed number \'n\'
---
--- >>> pz @(Cycle 5 Id) [1,2]
--- PresentT [1,2,1,2,1]
---
-data Cycle n p
-
-instance (Show a
-        , Show (t a)
-        , PP p x ~ t a
-        , P p x
-        , Integral (PP n x)
-        , P n x
-        , Foldable t
-        ) => P (Cycle n p) x where
-  type PP (Cycle n p) x = [ExtractAFromTA (PP p x)]
-  eval _ opts x = do
-    let msg0 = "Cycle"
-    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (fromIntegral -> n,p,nn,pp) ->
-        let hhs = [hh nn, hh pp]
-        in case chkSize opts msg0 p hhs of
-            Left e ->  e
-            Right () ->
-              let msg1 = msg0 <> "(" <> show n <> ")"
-                  d = take n (cycle (toList p))
-              in mkNode opts (PresentT d) (show01 opts msg1 d p) hhs
-
-data ProxyT' t
-
-instance P (ProxyT' t) x where
-  type PP (ProxyT' t) x = Proxy (PP t x)
-  eval _ opts _ =
-    pure $ mkNode opts (PresentT Proxy) "ProxyT" []
-
-data ProxyT (t :: Type)
-type ProxyTT (t :: Type) = ProxyT' (Hole t)
-
-instance P (ProxyT t) x where
-  type PP (ProxyT t) x = PP (ProxyTT t) x
-  eval _ = eval (Proxy @(ProxyTT t))
-
--- | similar to 'Data.List.!!'
---
--- >>> pz @(Ix 4 "not found") ["abc","D","eF","","G"]
--- PresentT "G"
---
--- >>> pz @(Ix 40 "not found") ["abc","D","eF","","G"]
--- PresentT "not found"
---
-data Ix (n :: Nat) def
-
-instance (P def (Proxy a)
-        , PP def (Proxy a) ~ a
-        , KnownNat n
-        , Show a
-        ) => P (Ix n def) [a] where
-  type PP (Ix n def) [a] = a
-  eval _ opts as = do
-    let n = nat @n
-        msg0 = "Ix(" <> show n <> ")"
-    case as ^? ix n of
-         Nothing -> do
-           let msg1 = msg0 <> " not found"
-           pp <- eval (Proxy @def) opts (Proxy @a)
-           pure $ case getValueLR opts msg1 pp [] of
-             Left e -> e
-             Right _ -> mkNode opts (_tBool pp) msg1 [hh pp]
-         Just a -> pure $ mkNode opts (PresentT a) (msg0 <> " " <> showL opts a) []
-
-data Ix' (n :: Nat)
-type IxT' (n :: Nat) = Ix n (Failp "Ix index not found")
-
-instance P (IxT' n) x => P (Ix' n) x where
-  type PP (Ix' n) x = PP (IxT' n) x
-  eval _ = eval (Proxy @(IxT' n))
-
--- | similar to 'Data.List.!!' leveraging 'Ixed'
---
--- >>> pz @(IxL Id 2 "notfound") ["abc","D","eF","","G"]
--- PresentT "eF"
---
--- >>> pz @(IxL Id 20 "notfound") ["abc","D","eF","","G"]
--- PresentT "notfound"
---
-data IxL p q def -- p is the big value and q is the index and def is the default
-
-instance (P q a
-        , P p a
-        , Show (PP p a)
-        , Ixed (PP p a)
-        , PP q a ~ Index (PP p a)
-        , Show (Index (PP p a))
-        , Show (IxValue (PP p a))
-        , P r (Proxy (IxValue (PP p a)))
-        , PP r (Proxy (IxValue (PP p a))) ~ IxValue (PP p a)
-        )
-   => P (IxL p q r) a where
-  type PP (IxL p q r) a = IxValue (PP p a)
-  eval _ opts a = do
-    let msg0 = "IxL"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> "(" <> show q <> ")"
-        in case p ^? ix q of
-             Nothing -> do
-                rr <- eval (Proxy @r) opts (Proxy @(IxValue (PP p a)))
-                pure $ case getValueLR opts msg1 rr [hh pp, hh qq] of
-                  Left e -> e
-                  Right _ -> mkNode opts (_tBool rr) (msg1 <> " index not found") [hh pp, hh qq]
-             Just ret -> pure $ mkNode opts (PresentT ret) (show01' opts msg1 ret "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
--- | similar to 'Data.List.!!' leveraging 'Ixed'
---
--- >>> pz @(Id !! 2) ["abc","D","eF","","G"]
--- PresentT "eF"
---
--- >>> pz @(Id !! 20) ["abc","D","eF","","G"]
--- FailT "(!!) index not found"
---
--- >>> import qualified Data.Map.Strict as M
--- >>> pz @(Id !! "eF") (M.fromList (flip zip [0..] ["abc","D","eF","","G"]))
--- PresentT 2
---
-data p !! q
-type BangBangT p q = IxL p q (Failp "(!!) index not found")
-
-instance P (BangBangT p q) a => P (p !! q) a where
-  type PP (p !! q) a = PP (BangBangT p q) a
-  eval _ = eval (Proxy @(BangBangT p q))
-
--- | 'lookup' leveraging 'Ixed'
---
--- >>> pz @(Lookup Id 2) ["abc","D","eF","","G"]
--- PresentT (Just "eF")
---
--- >>> pz @(Lookup Id 20) ["abc","D","eF","","G"]
--- PresentT Nothing
---
--- >>> pl @((Id !!? Char1 "d") > MkJust 99 || Length Id <= 3) (M.fromList $ zip "abcd" [1..])
--- False (False || False | (Just 4 > Just 99) || (4 <= 3))
--- FalseT
---
--- >>> pz @((Id !!? Char1 "d") > MkJust 2 || Length Id <= 3) (M.fromList $ zip "abcd" [1..])
--- TrueT
---
-data Lookup p q
-
-instance (P q a
-        , P p a
-        , Show (PP p a)
-        , Ixed (PP p a)
-        , PP q a ~ Index (PP p a)
-        , Show (Index (PP p a))
-        , Show (IxValue (PP p a))
-        )
-   => P (Lookup p q) a where
-  type PP (Lookup p q) a = Maybe (IxValue (PP p a))
-  eval _ opts a = do
-    let msg0 = "Lookup"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let msg1 = msg0 <> "(" <> show q <> ")"
-            hhs = [hh pp, hh qq]
-        in case p ^? ix q of
-             Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " not found") hhs
-             Just ret -> mkNode opts (PresentT (Just ret)) (show01' opts msg1 ret "p=" p <> showVerbose opts " | q=" q) hhs
-
-data p !!? q
-type BangBangQT p q = Lookup p q
-
-instance P (BangBangQT p q) a => P (p !!? q) a where
-  type PP (p !!? q) a = PP (BangBangQT p q) a
-  eval _ = eval (Proxy @(BangBangQT p q))
-
-
--- | 'Data.List.ands'
---
--- >>> pz @(Ands Id) [True,True,True]
--- TrueT
---
--- >>> pl @(Ands Id) [True,True,True,False]
--- False (Ands(4) i=3 | [True,True,True,False])
--- FalseT
---
--- >>> pz @(Ands Id) []
--- TrueT
---
-data Ands p
-
-instance (PP p x ~ t a
-        , P p x
-        , Show (t a)
-        , Foldable t
-        , a ~ Bool
-        ) => P (Ands p) x where
-  type PP (Ands p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Ands"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let msg1 = msg0 ++ "(" ++ show (length p) ++ ")"
-            w = case findIndex not (toList p) of
-                  Nothing -> ""
-                  Just i -> " i="++show i
-        in mkNodeB opts (and p) (msg1 <> w <> showVerbose opts " | " p) [hh pp]
-
--- | 'Data.List.ors'
---
--- >>> pz @(Ors Id) [False,False,False]
--- FalseT
---
--- >>> pl @(Ors Id) [True,True,True,False]
--- True (Ors(4) i=0 | [True,True,True,False])
--- TrueT
---
--- >>> pl @(Ors Id) []
--- False (Ors(0) | [])
--- FalseT
---
-data Ors p
-
-instance (PP p x ~ t a
-        , P p x
-        , Show (t a)
-        , Foldable t
-        , a ~ Bool
-        ) => P (Ors p) x where
-  type PP (Ors p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Ors"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let msg1 = msg0 ++ "(" ++ show (length p) ++ ")"
-            w = case findIndex id (toList p) of
-                  Nothing -> ""
-                  Just i -> " i="++show i
-        in mkNodeB opts (or p) (msg1 <> w <> showVerbose opts " | " p) [hh pp]
-
-
--- | similar to (++)
---
--- >>> pz @(Fst Id ++ Snd Id) ([9,10,11],[1,2,3,4])
--- PresentT [9,10,11,1,2,3,4]
---
--- >>> pz @(Snd Id ++ Fst Id) ([],[5])
--- PresentT [5]
---
--- >>> pz @(Char1 "xyz" :+ W "ab" ++ W "cdefg") ()
--- PresentT "xabcdefg"
---
--- >>> pz @([1,2,3] ++ EmptyList _) "somestuff"
--- PresentT [1,2,3]
---
-data p ++ q
-infixr 5 ++
-
-instance (P p x
-        , P q x
-        , Show (PP p x)
-        , PP p x ~ [a]
-        , PP q x ~ [a]
-        ) => P (p ++ q) x where
-  type PP (p ++ q) x = PP q x
-  eval _ opts z = do
-    let msg0 = "(++)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = p ++ q
-        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
-
-
--- cant directly create a singleton type using '[] since the type of '[] is unknown. instead use 'Singleton' or 'EmptyT'
-
--- | similar to cons
---
--- >>> pz @(Fst Id :+ Snd Id) (99,[1,2,3,4])
--- PresentT [99,1,2,3,4]
---
--- >>> pz @(Snd Id :+ Fst Id) ([],5)
--- PresentT [5]
---
--- >>> pz @(123 :+ EmptyList _) "somestuff"
--- PresentT [123]
---
-data p :+ q
-infixr 5 :+
-
-instance (P p x
-        , P q x
-        , Show (PP p x)
-        , Show (PP q x)
-        , Cons (PP q x) (PP q x) (PP p x) (PP p x)
-        ) => P (p :+ q) x where
-  type PP (p :+ q) x = PP q x
-  eval _ opts z = do
-    let msg0 = "(:+)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = p `cons` q
-        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
--- | similar to snoc
---
--- >>> pz @(Snd Id +: Fst Id) (99,[1,2,3,4])
--- PresentT [1,2,3,4,99]
---
--- >>> pz @(Fst Id +: Snd Id) ([],5)
--- PresentT [5]
---
--- >>> pz @(EmptyT [] Id +: 5) 5
--- PresentT [5]
---
-data p +: q
-infixl 5 +:
-
-instance (P p x
-        , P q x
-        , Show (PP q x)
-        , Show (PP p x)
-        , Snoc (PP p x) (PP p x) (PP q x) (PP q x)
-        ) => P (p +: q) x where
-  type PP (p +: q) x = PP p x
-  eval _ opts z = do
-    let msg0 = "(+:)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = p `snoc` q
-        in mkNode opts (PresentT b) (show01' opts msg0 b "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
--- | 'Control.Lens.uncons'
---
--- >>> pz @Uncons [1,2,3,4]
--- PresentT (Just (1,[2,3,4]))
---
--- >>> pz @Uncons []
--- PresentT Nothing
---
--- >>> pz @Uncons (Seq.fromList "abc")
--- PresentT (Just ('a',fromList "bc"))
---
--- >>> pz @Uncons ("xyz" :: T.Text)
--- PresentT (Just ('x',"yz"))
---
-data Uncons
-
-instance (Show (ConsT s)
-        , Show s
-        , Cons s s (ConsT s) (ConsT s)
-        ) => P Uncons s where
-  type PP Uncons s = Maybe (ConsT s,s)
-  eval _ opts as =
-    let msg0 = "Uncons"
-        b = as ^? _Cons
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
-
--- | 'Control.Lens.unsnoc'
---
--- >>> pz @Unsnoc [1,2,3,4]
--- PresentT (Just ([1,2,3],4))
---
--- >>> pz @Unsnoc []
--- PresentT Nothing
---
--- >>> pz @Unsnoc ("xyz" :: T.Text)
--- PresentT (Just ("xy",'z'))
---
-data Unsnoc
-
-instance (Show (ConsT s)
-        , Show s
-        , Snoc s s (ConsT s) (ConsT s)
-        ) => P Unsnoc s where
-  type PP Unsnoc s = Maybe (s,ConsT s)
-  eval _ opts as =
-    let msg0 = "Unsnoc"
-        b = as ^? _Snoc
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
-
--- | similar to 'null' using 'AsEmpty'
---
--- >>> pz @IsEmpty [1,2,3,4]
--- FalseT
---
--- >>> pz @IsEmpty []
--- TrueT
---
--- >>> pz @IsEmpty LT
--- FalseT
---
--- >>> pz @IsEmpty EQ
--- TrueT
---
-data IsEmpty
-
-instance ( Show as
-         , AsEmpty as
-         ) => P IsEmpty as where
-  type PP IsEmpty as = Bool
-  eval _ opts as =
-    let b = has _Empty as
-    in pure $ mkNodeB opts b ("IsEmpty" <> showVerbose opts " | " as) []
-
-data Null' p
-
-instance (Show (t a)
-        , Foldable t
-        , t a ~ PP p x
-        , P p x
-        ) => P (Null' p) x where
-  type PP (Null' p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Null"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = null p
-        in mkNodeB opts b ("Null" <> showVerbose opts " | " p) [hh pp]
-
--- | similar to 'null' using 'Foldable'
---
--- >>> pz @Null [1,2,3,4]
--- FalseT
---
--- >>> pz @Null []
--- TrueT
---
--- >>> pz @Null Nothing
--- TrueT
---
-data Null
-type NullT = Null' Id
-instance P NullT a => P Null a where
-  type PP Null a = Bool
-  eval _ = evalBool (Proxy @NullT)
-
--- | similar to 'enumFromTo'
---
--- >>> pz @(2 ... 5) ()
--- PresentT [2,3,4,5]
---
--- >>> pz @('LT ... 'GT) ()
--- PresentT [LT,EQ,GT]
---
--- >>> pz @(EnumFromTo 'GT 'LT) ()
--- PresentT []
---
--- >>> pz @(EnumFromTo (Pred Id) (Succ Id)) (SG.Max 10)
--- PresentT [Max {getMax = 9},Max {getMax = 10},Max {getMax = 11}]
---
--- >>> pz @(EnumFromTo 1 20 >> Map '(Id, (If (Id `Mod` 3 == 0) "Fizz" "" <> If (Id `Mod` 5 == 0) "Buzz" "" )) Id) 123
--- PresentT [(1,""),(2,""),(3,"Fizz"),(4,""),(5,"Buzz"),(6,"Fizz"),(7,""),(8,""),(9,"Fizz"),(10,"Buzz"),(11,""),(12,"Fizz"),(13,""),(14,""),(15,"FizzBuzz"),(16,""),(17,""),(18,"Fizz"),(19,""),(20,"Buzz")]
---
-data EnumFromTo p q
-data p ... q
-infix 4 ...
-
-type EnumFromToT p q = EnumFromTo p q
-
-instance P (EnumFromToT p q) x => P (p ... q) x where
-  type PP (p ... q) x = PP (EnumFromToT p q) x
-  eval _ = eval (Proxy @(EnumFromToT p q))
-
-instance (P p x
-        , P q x
-        , PP p x ~ a
-        , Show a
-        , PP q x ~ a
-        , Enum a
-        ) => P (EnumFromTo p q) x where
-  type PP (EnumFromTo p q) x = [PP p x]
-  eval _ opts z = do
-    let msg0 = "..."
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) -> mkNode opts (PresentT (enumFromTo p q)) (showL opts p <> " " <> msg0 <> " " <> showL opts q) [hh pp, hh qq]
-
--- | similar to 'enumFromThenTo'
---
--- >>> pz @(EnumFromThenTo (ToEnum Day 10) (ToEnum Day 20) (ToEnum Day 70)) ()
--- PresentT [1858-11-27,1858-12-07,1858-12-17,1858-12-27,1859-01-06,1859-01-16,1859-01-26]
---
--- >>> pz @(EnumFromThenTo (ReadP Day "2020-01-12") (ReadP Day "2020-02-12") (ReadP Day "2020-08-12")) ()
--- PresentT [2020-01-12,2020-02-12,2020-03-14,2020-04-14,2020-05-15,2020-06-15,2020-07-16]
---
-data EnumFromThenTo p q r
-
-instance (P p x
-        , P q x
-        , P r x
-        , PP p x ~ a
-        , Show a
-        , PP q x ~ a
-        , PP r x ~ a
-        , Enum a
-        ) => P (EnumFromThenTo p q r) x where
-  type PP (EnumFromThenTo p q r) x = [PP p x]
-  eval _ opts z = do
-    let msg0 = "EnumFromThenTo"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts z []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        rr <- eval (Proxy @r) opts z
-        pure $ case getValueLR opts (msg0 ++ " r failed") rr [hh pp, hh qq] of
-          Left e -> e
-          Right r ->
-            mkNode opts (PresentT (enumFromThenTo p q r)) (msg0 <> " [" <> showL opts p <> ", " <> showL opts q <> " .. " <> showL opts r <> "]") [hh pp, hh qq, hh rr]
-
--- | similar to 'partitionEithers'
---
--- >>> pz @PartitionEithers [Left 'a',Right 2,Left 'c',Right 4,Right 99]
--- PresentT ("ac",[2,4,99])
---
--- >>> pz @PartitionEithers [Right 2,Right 4,Right 99]
--- PresentT ([],[2,4,99])
---
--- >>> pz @PartitionEithers [Left 'a',Left 'c']
--- PresentT ("ac",[])
---
--- >>> pz @PartitionEithers ([] :: [Either () Int])
--- PresentT ([],[])
---
-data PartitionEithers
-
-instance ( Show a
-         , Show b
-         ) => P PartitionEithers [Either a b] where
-  type PP PartitionEithers [Either a b] = ([a], [b])
-  eval _ opts as =
-    let msg0 = "PartitionEithers"
-        b = partitionEithers as
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
-
--- | similar to 'partitionThese'. returns a 3-tuple with the results so use 'Fst' 'Snd' 'Thd' to extract
---
--- >>> pz @PartitionThese [This 'a', That 2, This 'c', These 'z' 1, That 4, These 'a' 2, That 99]
--- PresentT ("ac",[2,4,99],[('z',1),('a',2)])
---
-data PartitionThese
-
-instance ( Show a
-         , Show b
-         ) => P PartitionThese [These a b] where
-  type PP PartitionThese [These a b] = ([a], [b], [(a, b)])
-  eval _ opts as =
-    let msg0 = "PartitionThese"
-        b = partitionThese as
-    in pure $ mkNode opts (PresentT b) (show01 opts msg0 b as) []
-
-data Thiss
-type ThissT = Fst PartitionThese
-
-instance P ThissT x => P Thiss x where
-  type PP Thiss x = PP ThissT x
-  eval _ = eval (Proxy @ThissT)
-
-data Thats
-type ThatsT = Snd PartitionThese
-
-instance P ThatsT x => P Thats x where
-  type PP Thats x = PP ThatsT x
-  eval _ = eval (Proxy @ThatsT)
-
-data Theses
-type ThesesT = Thd PartitionThese
-
-instance P ThesesT x => P Theses x where
-  type PP Theses x = PP ThesesT x
-  eval _ = eval (Proxy @ThesesT)
-
--- want to pass Proxy b to q but then we have no way to calculate 'b'
-
--- | similar to 'scanl'
---
--- >>> pz @(Scanl (Snd Id :+ Fst Id) (Fst Id) (Snd Id)) ([99],[1..5])
--- PresentT [[99],[1,99],[2,1,99],[3,2,1,99],[4,3,2,1,99],[5,4,3,2,1,99]]
---
--- >>> pz @(ScanN 4 Id (Succ Id)) 'c'
--- PresentT "cdefg"
---
--- >>> pz @(FoldN 4 Id (Succ Id)) 'c'
--- PresentT 'g'
---
--- >>> pz @(Dup >> ScanN 4 Id (Pred Id *** Succ Id)) 'g'
--- PresentT [('g','g'),('f','h'),('e','i'),('d','j'),('c','k')]
---
-data Scanl p q r
--- scanr :: (a -> b -> b) -> b -> [a] -> [b]
--- result is scanl but signature is flipped ((a,b) -> b) -> b -> [a] -> [b]
-
-instance (PP p (b,a) ~ b
-        , PP q x ~ b
-        , PP r x ~ [a]
-        , P p (b,a)
-        , P q x
-        , P r x
-        , Show b
-        , Show a
-        )
-     => P (Scanl p q r) x where
-  type PP (Scanl p q r) x = [PP q x]
-  eval _ opts z = do
-    let msg0 = "Scanl"
-    lr <- runPQ msg0 (Proxy @q) (Proxy @r) opts z []
-    case lr of
-      Left e -> pure e
-      Right (q,r,qq,rr) ->
-        case chkSize opts msg0 r [hh rr] of
-          Left e -> pure e
-          Right () -> do
-            let ff i b as' rs
-                   | i >= oRecursion opts = pure (rs, Left $ mkNode opts (FailT (msg0 <> ":recursion limit i=" <> showIndex i)) ("(b,as')=" <> showL opts (b,as')) [])
-                   | otherwise =
-                       case as' of
-                         [] -> pure (rs, Right ()) -- ++ [((i,q), mkNode opts (PresentT q) (msg0 <> "(done)") [])], Right ())
-                         a:as -> do
-                            pp :: TT b <- evalHide (Proxy @p) opts (b,a)
-                            case getValueLR opts (msg0 <> " i=" <> showIndex i <> " a=" <> show a) pp [] of
-                               Left e  -> pure (rs,Left e)
-                               Right b' -> ff (i+1) b' as (rs ++ [((i,b), pp)])
-            (ts,lrx) :: ([((Int, b), TT b)], Either (TT [b]) ()) <- ff 1 q r []
-            pure $ case splitAndAlign opts msg0 (((0,q), mkNode opts (PresentT q) (msg0 <> "(initial)") []) : ts) of
-                 Left e -> errorInProgram $ "Scanl e=" ++ show (fromTT e)
-                 Right abcs ->
-                   let vals = map (view _1) abcs
-                       itts = map (view _2 &&& view _3) abcs
-                   in case lrx of
-                        Left e -> mkNode opts (_tBool e) msg0 (hh qq : hh rr : map (hh . fixit) itts ++ [hh e])
-                        Right () -> mkNode opts (PresentT vals) (show01' opts msg0 vals "b=" q <> showVerbose opts " | as=" r) (hh qq : hh rr : map (hh . fixit) itts)
-
-data ScanN n p q
-type ScanNT n p q = Scanl (Fst Id >> q) p (EnumFromTo 1 n) -- n times using q then run p
-
-instance P (ScanNT n p q) x => P (ScanN n p q) x where
-  type PP (ScanN n p q) x = PP (ScanNT n p q) x
-  eval _ = eval (Proxy @(ScanNT n p q))
-
-data ScanNA q
-type ScanNAT q = ScanN (Fst Id) (Snd Id) q
-
-instance P (ScanNAT q) x => P (ScanNA q) x where
-  type PP (ScanNA q) x = PP (ScanNAT q) x
-  eval _ = eval (Proxy @(ScanNAT q))
-
-data FoldN n p q
-type FoldNT n p q = Last (ScanN n p q)
-
-instance P (FoldNT n p q) x => P (FoldN n p q) x where
-  type PP (FoldN n p q) x = PP (FoldNT n p q) x
-  eval _ = eval (Proxy @(FoldNT n p q))
-
-data FoldL p q r
-type FoldLT p q r = Last (Scanl p q r)
-
-instance P (FoldLT p q r) x => P (FoldL p q r) x where
-  type PP (FoldL p q r) x = PP (FoldLT p q r) x
-  eval _ = eval (Proxy @(FoldLT p q r))
-
--- | similar to 'unfoldr'
---
--- >>> pz @(Unfoldr (MaybeBool (Not Null) (SplitAt 2 Id)) Id) [1..5]
--- PresentT [[1,2],[3,4],[5]]
---
-data Unfoldr p q
---type IterateN (t :: Type) n f = Unfoldr (If (Fst Id == 0) (MkNothing t) (Snd Id &&& (Pred Id *** f) >> MkJust Id)) '(n, Id)
-
-instance (PP q a ~ s
-        , PP p s ~ Maybe (b,s)
-        , P q a
-        , P p s
-        , Show s
-        , Show b
-          )
-     => P (Unfoldr p q) a where
-  type PP (Unfoldr p q) a = [UnfoldT (PP p (PP q a))]
-  eval _ opts z = do
-    let msg0 = "Unfoldr"
-    qq <- eval (Proxy @q) opts z
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q -> do
-        let msg1 = msg0 <> " " <> showL opts q
-            ff i s rs | i >= oRecursion opts = pure (rs, Left $ mkNode opts (FailT (msg1 <> ":recursion limit i=" <> showIndex i)) ("s=" <> showL opts s) [])
-                      | otherwise = do
-                              pp :: TT (PP p s) <- evalHide (Proxy @p) opts s
-                              case getValueLR opts (msg1 <> " i=" <> showIndex i <> " s=" <> show s) pp [] of
-                                   Left e  -> pure (rs, Left e)
-                                   Right Nothing -> pure (rs, Right ())
-                                   Right w@(Just (_b,s')) -> ff (i+1) s' (rs ++ [((i,w), pp)])
-        (ts,lr) :: ([((Int, PP p s), TT (PP p s))], Either (TT [b]) ()) <- ff 1 q []
-        pure $ case splitAndAlign opts msg1 ts of
-             Left e -> errorInProgram $ "Unfoldr e=" ++ show (fromTT e)
-             Right abcs ->
-               let vals = map (view _1) abcs
-                   itts = map (view _2 &&& view _3) abcs
-               in case lr of
-                   Left e -> mkNode opts (_tBool e) msg1 (hh qq : map (hh . fixit) itts ++ [hh e])
-                   Right () ->
-                     let ret = fst <$> catMaybes vals
-                     in mkNode opts (PresentT ret) (show01' opts msg1 ret "s=" q ) (hh qq : map (hh . fixit) itts)
-
-type family UnfoldT mbs where
-  UnfoldT (Maybe (b,s)) = b
-
--- | like 'iterate' but for a fixed number of elements
---
--- >>> pz @(IterateN 4 (Succ Id)) 4
--- PresentT [4,5,6,7]
---
--- >>> pz @('(0,1) >> IterateN 20 '(Snd Id, Fst Id + Snd Id) >> Map (Fst Id) Id) "sdf"
--- PresentT [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181]
---
-data IterateN n f
-type IterateNT n f = Unfoldr (MaybeBool (Fst Id > 0) '(Snd Id, Pred Id *** f)) '(n, Id)
-
-instance P (IterateNT n f) x => P (IterateN n f) x where
-  type PP (IterateN n f) x = PP (IterateNT n f) x
-  eval _ = eval (Proxy @(IterateNT n f))
-
-data IterateUntil p f
-type IterateUntilT p f = IterateWhile (Not p) f
-
-instance P (IterateUntilT p f) x => P (IterateUntil p f) x where
-  type PP (IterateUntil p f) x = PP (IterateUntilT p f) x
-  eval _ = eval (Proxy @(IterateUntilT p f))
-
-data IterateWhile p f
-type IterateWhileT p f = Unfoldr (MaybeBool p '(Id, f)) Id
-
-instance P (IterateWhileT p f) x => P (IterateWhile p f) x where
-  type PP (IterateWhile p f) x = PP (IterateWhileT p f) x
-  eval _ = eval (Proxy @(IterateWhileT p f))
-
-data IterateNWhile n p f
-type IterateNWhileT n p f = '(n, Id) >> IterateWhile (Fst Id > 0 && (Snd Id >> p)) (Pred Id *** f) >> Map (Snd Id) Id
-
-instance P (IterateNWhileT n p f) x => P (IterateNWhile n p f) x where
-  type PP (IterateNWhile n p f) x = PP (IterateNWhileT n p f) x
-  eval _ = eval (Proxy @(IterateNWhileT n p f))
-
-data IterateNUntil n p f
-type IterateNUntilT n p f = IterateNWhile n (Not p) f
-
-instance P (IterateNUntilT n p f) x => P (IterateNUntil n p f) x where
-  type PP (IterateNUntil n p f) x = PP (IterateNUntilT n p f) x
-  eval _ = eval (Proxy @(IterateNUntilT n p f))
-
--- | similar to 'map'
---
--- >>> pz @(Map (Pred Id) Id) [1..5]
--- PresentT [0,1,2,3,4]
---
-data Map p q
-
-instance (Show (PP p a)
-        , P p a
-        , PP q x ~ f a
-        , P q x
-        , Show a
-        , Show (f a)
-        , Foldable f
-        ) => P (Map p q) x where
-  type PP (Map p q) x = [PP p (ExtractAFromTA (PP q x))]
-  eval _ opts x = do
-    let msg0 = "Map"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q -> do
-        ts <- zipWithM (\i a -> ((i, a),) <$> evalHide (Proxy @p) opts a) [0::Int ..] (toList q)
-        pure $ case splitAndAlign opts msg0 ts of
-             Left e -> e
-             Right abcs ->
-               let vals = map (view _1) abcs
-               in mkNode opts (PresentT vals) (show01 opts msg0 vals q) (hh qq : map (hh . fixit) ts)
-
-data ConcatMap p q
-type ConcatMapT p q = Concat (Map p q)
-
-instance P (ConcatMapT p q) x => P (ConcatMap p q) x where
-  type PP (ConcatMap p q) x = PP (ConcatMapT p q) x
-  eval _ = eval (Proxy @(ConcatMapT p q))
-
--- | if p then run q else run r
---
--- >>> pz @(If (Gt 4) "greater than 4" "less than or equal to 4" ) 10
--- PresentT "greater than 4"
---
--- >>> pz @(If (Gt 4) "greater than 4" "less than or equal to 4") 0
--- PresentT "less than or equal to 4"
---
--- >>> pz @(If (Snd Id == "a") '("xxx",Fst Id + 13) (If (Snd Id == "b") '("yyy",Fst Id + 7) (Failt _ "oops"))) (99,"b")
--- PresentT ("yyy",106)
---
-data If p q r
-
-instance (Show (PP r a)
-        , P p a
-        , PP p a ~ Bool
-        , P q a
-        , P r a
-        , PP q a ~ PP r a
-        ) => P (If p q r) a where
-  type PP (If p q r) a = PP q a
-  eval _ opts a = do
-    let msg0 = "If"
-    pp <- evalBool (Proxy @p) opts a
-    case getValueLR opts (msg0 <> " condition failed") pp [] of
-      Left e -> pure e
-      Right b -> do
-        qqrr <- if b
-              then eval (Proxy @q) opts a
-              else eval (Proxy @r) opts a
-        pure $ case getValueLR opts (msg0 <> " [" <> show b <> "]") qqrr [hh pp, hh qqrr] of
-          Left e -> e
-          Right ret -> mkNode opts (_tBool qqrr) (msg0 <> " " <> if b then "(true cond)" else "(false cond)" <> " " <> showL opts ret) [hh pp, hh qqrr]
-
--- | creates a list of overlapping pairs of elements. requires two or more elements
---
--- >>> pz @Pairs [1,2,3,4]
--- PresentT [(1,2),(2,3),(3,4)]
---
--- >>> pz @Pairs []
--- FailT "Pairs no data found"
---
--- >>> pz @Pairs [1]
--- FailT "Pairs only one element found"
---
-data Pairs
-instance Show a => P Pairs [a] where
-  type PP Pairs [a] = [(a,a)]
-  eval _ opts as =
-    let msg0 = "Pairs"
-        lr = case as of
-               [] -> Left (msg0 <> " no data found")
-               [_] -> Left (msg0 <> " only one element found")
-               _:bs@(_:_) -> Right (zip as bs)
-    in pure $ case lr of
-         Left e -> mkNode opts (FailT e) e []
-         Right zs -> mkNode opts (PresentT zs) (show01 opts msg0 zs as ) []
-
-
--- | similar to 'partition'
---
--- >>> pz @(Partition (Ge 3) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([10,4,7,3,3,5],[1,1])
---
--- >>> pz @(Partition (Prime Id) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([7,3,3,5],[10,4,1,1])
---
--- >>> pz @(Partition (Ge 300) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([],[10,4,1,7,3,1,3,5])
---
--- >>> pz @(Partition (Id < 300) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([10,4,1,7,3,1,3,5],[])
---
-data Partition p q
-
-instance (P p x
-        , Show x
-        , PP q a ~ [x]
-        , PP p x ~ Bool
-        , P q a
-        ) => P (Partition p q) a where
-  type PP (Partition p q) a = (PP q a, PP q a)
-  eval _ opts a' = do
-    let msg0 = "Partition"
-    qq <- eval (Proxy @q) opts a'
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-             ts <- zipWithM (\i a -> ((i, a),) <$> evalBoolHide (Proxy @p) opts a) [0::Int ..] q
-             pure $ case splitAndAlign opts msg0 ts of
-               Left e -> e
-               Right abcs ->
-                 let itts = map (view _2 &&& view _3) abcs
-                     w0 = partition (view _1) abcs
-                     zz1 = (map (view (_2 . _2)) *** map (view (_2 . _2))) w0
-                 in mkNode opts (PresentT zz1) (show01' opts msg0 zz1 "s=" q) (hh qq : map (hh . fixit) itts)
-
-
--- | partition values based on a function
---
--- >>> pz @(PartitionBy Ordering (Case 'EQ '[Id < 0, Id > 0] '[ 'LT, 'GT] Id) Id) [-4,-2,5,6,7,0,-1,2,-3,4,0]
--- PresentT (fromList [(LT,[-3,-1,-2,-4]),(EQ,[0,0]),(GT,[4,2,7,6,5])])
---
--- >>> pl @(PartitionBy Ordering (Case (Failt _ "asdf") '[Id < 2, Id == 2, Id > 2] '[ 'LT, 'EQ, 'GT] Id) Id) [-4,2,5,6,7,1,2,3,4]
--- Present fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])] (PartitionBy fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])] | s=[-4,2,5,6,7,1,2,3,4])
--- PresentT (fromList [(LT,[1,-4]),(EQ,[2,2]),(GT,[4,3,7,6,5])])
---
--- >>> pl @(PartitionBy Ordering (Case (Failt _ "xyzxyzxyzzyyysyfsyfydf") '[Id < 2, Id == 2, Id > 3] '[ 'LT, 'EQ, 'GT] Id) Id) [-4,2,5,6,7,1,2,3,4]
--- Error xyzxyzxyzzyyysyfsyfydf (PartitionBy(i=7, a=3) excnt=1)
--- FailT "xyzxyzxyzzyyysyfsyfydf"
---
-data PartitionBy t p q
-
-instance (P p x
-        , Ord t
-        , Show x
-        , Show t
-        , PP q a ~ [x]
-        , PP p x ~ t
-        , P q a
-        ) => P (PartitionBy t p q) a where
-  type PP (PartitionBy t p q) a = M.Map t (PP q a)
-  eval _ opts a' = do
-    let msg0 = "PartitionBy"
-    qq <- eval (Proxy @q) opts a'
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-             ts <- zipWithM (\i a -> ((i, a),) <$> evalHide (Proxy @p) opts a) [0::Int ..] q
-             pure $ case splitAndAlign opts msg0 ts of
-                   Left e -> e
-                   Right abcs ->
-                     let kvs = map (view _1 &&& ((:[]) . view (_2 . _2))) abcs
-                         itts = map (view _2 &&& view _3) abcs
-                         ret = M.fromListWith (++) kvs
-                     in mkNode opts (PresentT ret) (show01' opts msg0 ret "s=" q ) (hh qq : map (hh . fixit) itts)
-
--- | similar to 'groupBy'
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,3,4,5,1,5,5]
--- PresentT [[1],[3],[4],[5],[1],[5,5]]
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,1,1,3,4,5,1,5,5]
--- PresentT [[1,1,1],[3],[4],[5],[1],[5,5]]
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [5,5]
--- PresentT [[5,5]]
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1,2]
--- PresentT [[1],[2]]
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) [1]
--- PresentT [[1]]
---
--- >>> pz @(GroupBy (Fst Id == Snd Id) Id) []
--- PresentT []
---
--- >>> pz @(GroupBy (Fst Id < Snd Id) Id) [1,2,3,4,4,1,2]
--- PresentT [[1,2,3,4],[4],[1,2]]
---
--- >>> pz @(GroupBy (Fst Id /= Snd Id) Id) [1,2,3,4,4,4,1]
--- PresentT [[1,2,3,4],[4],[4,1]]
---
--- >>> pan @(GroupBy (Fst Id == Snd Id) Id) "hello    goodbye"
--- P GroupBy ["h","e","ll","o","    ","g","oo","d","b","y","e"]
--- |
--- +- P Id "hello    goodbye"
--- |
--- +- False i=0:'h' == 'e'
--- |
--- +- False i=1:'e' == 'l'
--- |
--- +- True i=2:'l' == 'l'
--- |
--- +- False i=3:'l' == 'o'
--- |
--- +- False i=4:'o' == ' '
--- |
--- +- True i=5:' ' == ' '
--- |
--- +- True i=6:' ' == ' '
--- |
--- +- True i=7:' ' == ' '
--- |
--- +- False i=8:' ' == 'g'
--- |
--- +- False i=9:'g' == 'o'
--- |
--- +- True i=10:'o' == 'o'
--- |
--- +- False i=11:'o' == 'd'
--- |
--- +- False i=12:'d' == 'b'
--- |
--- +- False i=13:'b' == 'y'
--- |
--- `- False i=14:'y' == 'e'
--- PresentT ["h","e","ll","o","    ","g","oo","d","b","y","e"]
---
-data GroupBy p q
-
-instance (Show x
-        , PP q a ~ [x]
-        , PP p (x,x) ~ Bool
-        , P p (x,x)
-        , P q a
-        ) => P (GroupBy p q) a where
-  type PP (GroupBy p q) a = [PP q a]
-  eval _ opts a' = do
-    let msg0 = "GroupBy"
-    qq <- eval (Proxy @q) opts a'
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-             case q of
-               [] -> pure $ mkNode opts (PresentT []) (show01' opts msg0 q "s=" q) [hh qq]
-               [_] -> pure $ mkNode opts (PresentT [q]) (show01' opts msg0 [q] "s=" q) [hh qq]
-               x:xs -> do
-                 ts <- zipWithM (\i (a,b) -> ((i, b),) <$> evalBoolHide (Proxy @p) opts (a,b)) [0::Int ..] (zip (x:xs) xs)
-                 pure $ case splitAndAlign opts msg0 ts of
-                   Left e -> e
-                   Right abcs ->
-                     let ret = gp1 x abcs
-                         itts = map (view _2 &&& view _3) abcs
-                     in mkNode opts (PresentT ret) (show01' opts msg0 ret "s=" q ) (hh qq : map (hh . fixit) itts)
-
-gp1 :: x -> [(Bool, (Int, x), TT Bool)] -> [[x]]
-gp1 b = go [b]
-  where
-  go ret =
-     \case
-       [] -> [ret]
-       (tf, (_, a), _):as -> if tf then go (ret <> [a]) as
-                             else ret : go [a] as
-
-data Filter p q
-type FilterT p q = Fst (Partition p q)
-
-instance P (FilterT p q) x => P (Filter p q) x where
-  type PP (Filter p q) x = PP (FilterT p q) x
-  eval _ = eval (Proxy @(FilterT p q))
-
--- | similar to 'break'
---
--- >>> pz @(Break (Ge 3) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([],[10,4,1,7,3,1,3,5])
---
--- >>> pz @(Break (Lt 3) Id) [10,4,1,7,3,1,3,5]
--- PresentT ([10,4],[1,7,3,1,3,5])
---
-data Break p q
-
--- only process up to the pivot! only process while Right False
--- a predicate can return PresentP not just TrueP
-instance (P p x
-        , PP q a ~ [x]
-        , PP p x ~ Bool
-        , P q a
-        ) => P (Break p q) a where
-  type PP (Break p q) a = (PP q a, PP q a)
-  eval _ opts a' = do
-    let msg0 = "Break"
-    qq <- eval (Proxy @q) opts a'
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case chkSize opts msg0 q [hh qq] of
-          Left e -> pure e
-          Right () -> do
-            let ff [] zs = pure (zs, [], Nothing) -- [(ia,qq)] extras | the rest of the data | optional last pivot or failure
-                ff ((i,a):ias) zs = do
-                   pp <- evalBoolHide (Proxy @p) opts a
-                   let v = ((i,a), pp)
-                   case getValueLR opts msg0 pp [hh qq] of
-                     Right False -> ff ias (zs Seq.|> v)
-                     Right True -> pure (zs,map snd ias,Just v)
-                     Left _ -> pure (zs,map snd ias,Just v)
-            (ialls,rhs,mpivot) <- ff (itoList q) Seq.empty
-            pure $ case mpivot of
-                 Nothing ->
-                   mkNode opts (PresentT (map (snd . fst) (toList ialls), rhs))
-                           (msg0 <> " cnt=" <> show (length ialls, length rhs))
-                           (map (hh . fixit) (toList ialls))
-                 Just iall@(ia, tt) ->
-                   case getValueLR opts (msg0 <> " predicate failed") tt (hh qq : map (hh . fixit) (toList (ialls Seq.|> iall))) of
-                     Right True ->
-                       mkNode opts (PresentT (map (snd . fst) (toList ialls), snd ia : rhs))
-                               (msg0 <> " cnt=" <> show (length ialls, 1+length rhs))
-                               (hh qq : hh tt : map (hh . fixit) (toList (ialls Seq.|> iall)))
-
-                     Right False -> errorInProgram "Break"
-                     Left e -> e
-
-data Span p q
-type SpanT p q = Break (Not p) q
-
-instance P (SpanT p q) x => P (Span p q) x where
-  type PP (Span p q) x = PP (SpanT p q) x
-  eval _ = eval (Proxy @(SpanT p q))
-
--- | Fails the computation with a message
---
--- >>> pz @(Failt Int (PrintF "value=%03d" Id)) 99
--- FailT "value=099"
---
--- >>> pz @(FailS (PrintT "value=%03d string=%s" Id)) (99,"somedata")
--- FailT "value=099 string=somedata"
---
-data Fail t prt
-
-instance (P prt a
-        , PP prt a ~ String
-        ) => P (Fail t prt) a where
-  type PP (Fail t prt) a = PP t a
-  eval _ opts a = do
-    let msg0 = "Fail"
-    pp <- eval (Proxy @prt) opts a
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right s -> mkNode opts (FailT s) (msg0 <> " " <> s) [hh pp | isVerbose opts]
-
-data FailS p
-instance P (Fail I p) x => P (FailS p) x where
-  type PP (FailS p) x = PP (Fail I p) x
-  eval _ = eval (Proxy @(Fail I p))
-
-data Failt (t :: Type) p
-instance P (Fail (Hole t) p) x => P (Failt t p) x where
-  type PP (Failt t p) x = PP (Fail (Hole t) p) x
-  eval _ = eval (Proxy @(Fail (Hole t) p))
-
-data Failp p
-instance P (Fail Unproxy p) x => P (Failp p) x where
-  type PP (Failp p) x = PP (Fail Unproxy p) x
-  eval _ = eval (Proxy @(Fail Unproxy p))
-
-data Hole (t :: Type)
-
--- | Acts as a proxy in this dsl where you can explicitly set the Type.
---
---  It is passed around as an argument to help the type checker when needed.
---  see 'ParseTimeP', 'ReadBase'
---
-instance Typeable t => P (Hole t) a where
-  type PP (Hole t) a = t -- can only be Type not Type -> Type (can use Proxy but then we go down the rabbithole)
-  eval _ opts _a =
-    let msg0 = "Hole(" <> showT @t <> ")"
-    in pure $ mkNode opts (FailT msg0) "you probably meant to get access to the type of PP only and not evaluate" []
-
-data Unproxy
-
-instance Typeable a => P Unproxy (Proxy (a :: Type)) where
-  type PP Unproxy (Proxy a) = a
-  eval _ opts _a =
-    let msg0 = "Unproxy(" <> showT @a <> ")"
-    in pure $ mkNode opts (FailT msg0) "you probably meant to get access to the type of PP only and not evaluate" []
-
--- | catch a failure
---
--- >>> pz @(Catch (Succ Id) (Fst Id >> Second (ShowP Id) >> PrintT "%s %s" Id >> 'LT)) GT
--- PresentT LT
---
--- >>> pz @(Catch' (Succ Id) (Second (ShowP Id) >> PrintT "%s %s" Id)) GT
--- FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument GT"
---
--- >>> pz @(Catch' (Succ Id) (Second (ShowP Id) >> PrintT "%s %s" Id)) LT
--- PresentT EQ
---
--- >>> pz @(Len > 1 && Catch (Id !! 3 == 66) 'False) [1,2]
--- FalseT
---
--- more flexible: takes a (String,x) and a proxy so we can still call 'False 'True
--- now takes the FailT string and x so you can print more detail if you want
--- need the proxy so we can fail without having to explicitly specify a type
-data Catch p q -- catch p and if fails runs q only on failt
-
-data Catch' p s
-type CatchT' p s = Catch p (FailCatch s) -- eg set eg s=PrintF "%d" Id or PrintF "%s" (ShowP Id)
-type FailCatch s = Fail (Snd Id >> Unproxy) (Fst Id >> s)
-
-instance P (CatchT' p s) x => P (Catch' p s) x where
-  type PP (Catch' p s) x = PP (CatchT' p s) x
-  eval _ = eval (Proxy @(CatchT' p s))
-
-instance (P p x
-        , P q ((String, x)
-        , Proxy (PP p x))
-        , PP p x ~ PP q ((String, x), Proxy (PP p x))
-        ) => P (Catch p q) x where
-  type PP (Catch p q) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Catch"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> do
-         let emsg = e ^?! tBool . _FailT -- extract the failt string a push back into the fail case
-         qq <- eval (Proxy @q) opts ((emsg, x), Proxy @(PP p x))
-         pure $ case getValueLR opts (msg0 <> " default condition failed") qq [hh pp] of
-            Left e1 -> e1
-            Right _ -> mkNode opts (_tBool qq) (msg0 <> " caught exception[" <> emsg <> "]") [hh pp, hh qq]
-      Right _ -> pure $ mkNode opts (_tBool pp) (msg0 <> " did not fire") [hh pp]
-
--- | similar to 'even'
---
--- >>> pz @(Map Even Id) [9,-4,12,1,2,3]
--- PresentT [False,True,True,False,True,False]
---
--- >>> pz @(Map '(Even,Odd) Id) [9,-4,12,1,2,3]
--- PresentT [(False,True),(True,False),(True,False),(False,True),(True,False),(False,True)]
---
-data Even
-type EvenT = Mod I 2 == 0
-
-instance P EvenT x => P Even x where
-  type PP Even x = Bool
-  eval _ = evalBool (Proxy @EvenT)
-
-data Odd
-type OddT = Mod I 2 == 1
-
-instance P OddT x => P Odd x where
-  type PP Odd x = Bool
-  eval _ = evalBool (Proxy @OddT)
-
-
---type Div' p q = Fst (DivMod p q)
---type Mod' p q = Snd (DivMod p q)
-
--- | similar to 'div'
---
--- >>> pz @(Div (Fst Id) (Snd Id)) (10,4)
--- PresentT 2
---
--- >>> pz @(Div (Fst Id) (Snd Id)) (10,0)
--- FailT "Div zero denominator"
---
-data Div p q
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Integral (PP p a)
-        ) => P (Div p q) a where
-  type PP (Div p q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "Div"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-         let hhs = [hh pp, hh qq]
-         in case q of
-              0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
-              _ -> let d = p `div` q
-                   in mkNode opts (PresentT d) (showL opts p <> " `div` " <> showL opts q <> " = " <> showL opts d) hhs
-
-
--- | similar to 'mod'
---
--- >>> pz @(Mod (Fst Id) (Snd Id)) (10,3)
--- PresentT 1
---
--- >>> pz @(Mod (Fst Id) (Snd Id)) (10,0)
--- FailT "Mod zero denominator"
---
-data Mod p q
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Integral (PP p a)
-        ) => P (Mod p q) a where
-  type PP (Mod p q) a = PP p a
-  eval _ opts a = do
-    let msg0 = "Mod"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-         let hhs = [hh pp, hh qq]
-         in case q of
-              0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
-              _ -> let d = p `mod` q
-                   in mkNode opts (PresentT d) (showL opts p <> " `mod` " <> showL opts q <> " = " <> showL opts d) hhs
-
--- | similar to 'divMod'
---
--- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,3)
--- PresentT (3,1)
---
--- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,-3)
--- PresentT (-4,-2)
---
--- >>> pz @(DivMod (Fst Id) (Snd Id)) (-10,3)
--- PresentT (-4,2)
---
--- >>> pz @(DivMod (Fst Id) (Snd Id)) (-10,-3)
--- PresentT (3,-1)
---
--- >>> pz @(DivMod (Fst Id) (Snd Id)) (10,0)
--- FailT "DivMod zero denominator"
---
-data DivMod p q
-
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Integral (PP p a)
-        ) => P (DivMod p q) a where
-  type PP (DivMod p q) a = (PP p a, PP p a)
-  eval _ opts a = do
-    let msg0 = "DivMod"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-        in case q of
-             0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
-             _ -> let d = p `divMod` q
-                  in mkNode opts (PresentT d) (showL opts p <> " `divMod` " <> showL opts q <> " = " <> showL opts d) hhs
-
--- | similar to 'quotRem'
---
--- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,3)
--- PresentT (3,1)
---
--- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,-3)
--- PresentT (-3,1)
---
--- >>> pz @(QuotRem (Fst Id) (Snd Id)) (-10,-3)
--- PresentT (3,-1)
---
--- >>> pz @(QuotRem (Fst Id) (Snd Id)) (-10,3)
--- PresentT (-3,-1)
---
--- >>> pz @(QuotRem (Fst Id) (Snd Id)) (10,0)
--- FailT "QuotRem zero denominator"
---
-data QuotRem p q
-
-instance (PP p a ~ PP q a
-        , P p a
-        , P q a
-        , Show (PP p a)
-        , Integral (PP p a)
-        ) => P (QuotRem p q) a where
-  type PP (QuotRem p q) a = (PP p a, PP p a)
-  eval _ opts a = do
-    let msg0 = "QuotRem"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-        in case q of
-             0 -> mkNode opts (FailT (msg0 <> " zero denominator")) "" hhs
-             _ -> let d = p `quotRem` q
-                  in mkNode opts (PresentT d) (showL opts p <> " `quotRem` " <> showL opts q <> " = " <> showL opts d) hhs
-
-data Quot p q
-type QuotT p q = Fst (QuotRem p q)
-
-instance P (QuotT p q) x => P (Quot p q) x where
-  type PP (Quot p q) x = PP (QuotT p q) x
-  eval _ = eval (Proxy @(QuotT p q))
-
-data Rem p q
-type RemT p q = Snd (QuotRem p q)
-
-instance P (RemT p q) x => P (Rem p q) x where
-  type PP (Rem p q) x = PP (RemT p q) x
-  eval _ = eval (Proxy @(RemT p q))
-
---type OneP = Guard "expected list of length 1" (Len == 1) >> Head Id
---type OneP = Guard (PrintF "expected list of length 1 but found length=%d" Len) (Len == 1) >> Head Id
-
--- k or prt has access to (Int,a) where Int is the current guard position: hence need to use PrintT
--- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out)
-
--- | Guards contain a type level list of tuples the action to run on failure of the predicate and the predicate itself
--- Each tuple validating against the corresponding value in a value list
---
--- \'prt\' receives (Int,a) as input which is the position and value if there is a failure
---
--- >>> pz @(Guards '[ '("arg1 failed",Gt 4), '("arg2 failed", Same 4)]) [17,4]
--- PresentT [17,4]
---
--- >>> pz @(Guards '[ '("arg1 failed",Gt 4), '("arg2 failed", Same 5)]) [17,4]
--- FailT "arg2 failed"
---
--- >>> pz @(Guards '[ '("arg1 failed",Gt 99), '("arg2 failed", Same 4)]) [17,4]
--- FailT "arg1 failed"
---
--- >>> pz @(Guards '[ '(PrintT "arg %d failed with value %d" Id,Gt 4), '(PrintT "%d %d" Id, Same 4)]) [17,3]
--- FailT "1 3"
---
--- >>> pz @(GuardsQuick (PrintT "arg %d failed with value %d" Id) '[Gt 4, Ge 3, Same 4]) [17,3,5]
--- FailT "arg 2 failed with value 5"
---
--- >>> pz @(GuardsQuick (PrintT "arg %d failed with value %d" Id) '[Gt 4, Ge 3, Same 4]) [17,3,5,99]
--- FailT "Guards:invalid length(4) expected 3"
---
-data GuardsImpl (n :: Nat) (os :: [(k,k1)])
-
-data Guards (ps :: [(k,k1)])
-
-instance ( [a] ~ x
-         , GetLen ps
-         , P (GuardsImpl (LenT ps) ps) x
-         ) => P (Guards ps) x where
-  type PP (Guards ps) x = PP (GuardsImpl (LenT ps) ps) x
-  eval _ opts as = do
-    let msg0 = "Guards"
-        n = getLen @ps
-    if n /= length as then
-       let msg1 = msg0 <> badLength as n
-       in pure $ mkNode opts (FailT msg1) "" []
-    else eval (Proxy @(GuardsImpl (LenT ps) ps)) opts as
-
-badLength :: ( Foldable t
-             , Show n
-             , Num n
-             ) => t a
-               -> n
-               -> String
-badLength as n = ":invalid length(" <> show (length as) <> ") expected " ++ show (n+0)
-
-instance ( [a] ~ x
-         , Show a
-         ) => P (GuardsImpl n ('[] :: [(k,k1)])) x where
-  type PP (GuardsImpl n ('[] :: [(k,k1)])) x = x
-  eval _ opts as =
-    let msg0 = "Guards"
-    in if not (null as) then errorInProgram $ "GuardsImpl base case has extra data " ++ show as
-       else pure $ mkNode opts (PresentT as) (msg0 <> " no data") []
-
-instance (PP prt (Int, a) ~ String
-        , P prt (Int, a)
-        , KnownNat n
-        , GetLen ps
-        , P p a
-        , PP p a ~ Bool
-        , P (GuardsImpl n ps) [a]
-        , PP (GuardsImpl n ps) [a] ~ [a]
-        , Show a
-        , [a] ~ x
-        ) => P (GuardsImpl n ('(prt,p) ': ps)) x where
-  type PP (GuardsImpl n ('(prt,p) ': ps)) x = x
-  eval _ opts as' = do
-     let cpos = n-pos-1
-         msgbase1 = "Guard(" <> show cpos <> ")"
-         msgbase2 = "Guards"
-         n :: Int
-         n = nat @n
-         pos = getLen @ps
-     case as' of
-         a:as -> do
-            pp <- evalBoolHide (Proxy @p) opts a
-            case getValueLR opts (msgbase1 <> " p failed") pp [] of
-                 Left e -> pure e
-                 Right False -> do
-                   qq <- eval (Proxy @prt) opts (cpos,a) -- only run prt when predicate is False
-                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
-                      Left e -> e
-                      Right msgx -> mkNode opts (FailT msgx) (msgbase1 <> " failed [" <> msgx <> "]" <> " " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
-                 Right True ->
-                   if pos == 0 then -- we are at the bottom of the tree
-                      pure $ mkNode opts (PresentT [a]) msgbase2 [hh pp]
-                   else do
-                     ss <- eval (Proxy @(GuardsImpl n ps)) opts as
-                     pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
-                       Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
-                       Right zs -> (ss & tForest %~ \x -> fromTT pp : x) & tBool .~ PresentT (a:zs)
-         _ -> errorInProgram "GuardsImpl n+1 case has no data"
-
-data GuardsQuick (prt :: k) (ps :: [k1])
-type GuardsQuickT (prt :: k) (ps :: [k1]) = Guards (ToGuardsT prt ps)
-
-instance P (GuardsQuickT prt ps) x => P (GuardsQuick prt ps) x where
-  type PP (GuardsQuick prt ps) x = PP (GuardsQuickT prt ps) x
-  eval _ = eval (Proxy @(GuardsQuickT prt ps))
-
--- | boolean guard which checks a given a list of predicates against the list of values
---
--- prefer 'Bools' as 'BoolsQuick' doesnt give much added value: passes in the index and the value to prt but you already have the index in the message
---
--- pulls the top message from the tree if a predicate is false
---
--- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ] ) [12,93,14]
--- False (Bool(1) [mm] (93 <= 59))
--- FalseT
---
--- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ] ) [12,13,94]
--- False (Bool(2) [<<<2 94>>>] (94 <= 59))
--- FalseT
---
--- >>> pl @(Bools '[ '(W "hh",Between 0 23 Id), '(W "mm",Between 0 59 Id), '(PrintT "<<<%d %d>>>" Id,Between 0 59 Id) ] ) [12,13,14]
--- True (Bools)
--- TrueT
---
--- >>> pl @(BoolsQuick "abc" '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,14]
--- True (Bools)
--- TrueT
---
--- >>> pl @(BoolsQuick (PrintT "id=%d val=%d" Id) '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,14]
--- True (Bools)
--- TrueT
---
--- >>> pl @(BoolsQuick (PrintT "id=%d val=%d" Id) '[Between 0 23 Id, Between 0 59 Id, Between 0 59 Id]) [12,13,99]
--- False (Bool(2) [id=2 val=99] (99 <= 59))
--- FalseT
---
--- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id) ] ) [12,13,14]
--- True (Bools)
--- TrueT
---
--- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id) ] ) [12,60,14]
--- False (Bool(1) [minutes] (60 <= 59))
--- FalseT
---
--- >>> pl @(Bools '[ '("hours",Between 0 23 Id), '("minutes",Between 0 59 Id), '("seconds",Between 0 59 Id) ] ) [12,60,14,20]
--- False (Bools:invalid length(4) expected 3)
--- FalseT
---
-data Bools (ps :: [(k,k1)])
-
-instance ([a] ~ x
-        , GetLen ps
-        , P (BoolsImpl (LenT ps) ps) x
-        , PP (BoolsImpl (LenT ps) ps) x ~ Bool
-        ) => P (Bools ps) x where
-  type PP (Bools ps) x = Bool
-  eval _ opts as = do
-    let msg0 = "Bools"
-        msg1 = "Bool("++show n++")"
-        n = getLen @ps
-    case chkSize opts msg1 as [] of
-      Left e -> pure e
-      Right () ->
-        if n /= length as then
-           let msg2 = msg0 <> badLength as n
-           in pure $ mkNodeB opts False msg2 [] -- was FailT but now just FalseT
-        else evalBool (Proxy @(BoolsImpl (LenT ps) ps)) opts as
-
-data BoolsImpl (n :: Nat) (os :: [(k,k1)])
-
-instance (KnownNat n
-        , Show a
-        , [a] ~ x
-        ) => P (BoolsImpl n ('[] :: [(k,k1)])) x where
-  type PP (BoolsImpl n ('[] :: [(k,k1)])) x = Bool
-  eval _ opts as =
-    let msg0 = "Bool(" <> show n <> ")"
-        n :: Int = nat @n
-    in if not (null as) then errorInProgram $ "BoolsImpl base case has extra data " ++ show as
-       else pure $ mkNodeB opts True (msg0 <> " empty") []
-
-instance (PP prt (Int, a) ~ String
-        , P prt (Int, a)
-        , KnownNat n
-        , GetLen ps
-        , P p a
-        , PP p a ~ Bool
-        , P (BoolsImpl n ps) x
-        , PP (BoolsImpl n ps) [a] ~ Bool
---        , Show a
-        , [a] ~ x
-        ) => P (BoolsImpl n ('(prt,p) ': ps)) x where
-  type PP (BoolsImpl n ('(prt,p) ': ps)) x = Bool
-  eval _ opts as' = do
-     let cpos = n-pos-1
-         msgbase1 = "Bool(" <> showIndex cpos <> ")"
-         msgbase2 = "Bools"
-         n :: Int = nat @n
-         pos = getLen @ps
-     case as' of
-         a:as -> do
-            pp <- evalBoolHide (Proxy @p) opts a
-            case getValueLR opts (msgbase1 <> " p failed") pp [] of
-                 Left e -> pure e
-                 Right False -> do
-                   qq <- eval (Proxy @prt) opts (cpos,a) -- only run prt when predicate is False
-                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
-                      Left e -> e
-                      Right msgx -> mkNodeB opts False (msgbase1 <> " [" <> msgx <> "] " <> topMessage pp) (hh pp : [hh qq | isVerbose opts])
-                 Right True ->
-                   if pos == 0 then -- we are at the bottom of the tree
-                      pure $ mkNodeB opts True msgbase2 [hh pp]
-                   else do
-                     ss <- evalBool (Proxy @(BoolsImpl n ps)) opts as
-                     pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
-                       Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
-                       Right _ ->  ss & tForest %~ \x -> fromTT pp : x
-         _ -> errorInProgram "BoolsImpl n+1 case has no data"
-
-data BoolsQuick (prt :: k) (ps :: [k1])
-type BoolsQuickT (prt :: k) (ps :: [k1]) = Bools (ToGuardsT prt ps)
-
--- why do we need this? when BoolsN works without [use the x ~ [a] trick in BoolsN]
-instance (PP (Bools (ToGuardsT prt ps)) x ~ Bool
-        , P (BoolsQuickT prt ps) x
-          ) => P (BoolsQuick prt ps) x where
-  type PP (BoolsQuick prt ps) x = PP (BoolsQuickT prt ps) x
-  eval _ = evalBool (Proxy @(BoolsQuickT prt ps))
-
--- | leverages 'RepeatT' for repeating predicates (passthrough method)
---
--- >>> pl @(BoolsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,256]
--- False (Bool(3) [id=3 must be between 0 and 255, found 256] (256 <= 255))
--- FalseT
---
--- >>> pl @(BoolsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,44]
--- True (Bools)
--- TrueT
---
-data BoolsN prt (n :: Nat) (p :: k1)
-type BoolsNT prt (n :: Nat) (p :: k1) = Bools (ToGuardsT prt (RepeatT n p))
-
-instance ( x ~ [a]
-         , P (BoolsNT prt n p) x
-         ) => P (BoolsN prt n p) x where
-  type PP (BoolsN prt n p) x = PP (BoolsNT prt n p) x
-  eval _ = evalBool (Proxy @(BoolsNT prt n p))
-
--- | if a predicate fails then then the corresponding symbol and value will be passed to the print function
---
--- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [13,59,61]
--- FailT "seconds invalid: found 61"
---
--- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [27,59,12]
--- FailT "hours invalid: found 27"
---
--- >>> pz @(GuardsDetail "%s invalid: found %d" '[ '("hours", Between 0 23 Id),'("minutes",Between 0 59 Id),'("seconds",Between 0 59 Id)]) [23,59,12]
--- PresentT [23,59,12]
---
-data GuardsDetailImpl (ps :: [(k,k1)])
-
-instance ([a] ~ x
-        , GetLen ps
-        , P (GuardsImplX (LenT ps) ps) x
-        ) => P (GuardsDetailImpl ps) x where
-  type PP (GuardsDetailImpl ps) x = PP (GuardsImplX (LenT ps) ps) x
-  eval _ opts as = do
-    let msg0 = "Guards"
-        n = getLen @ps
-    if n /= length as then
-       let msg1 = msg0 <> badLength as n
-       in pure $ mkNode opts (FailT msg1) "" []
-    else eval (Proxy @(GuardsImplX (LenT ps) ps)) opts as
-
-data GuardsImplX (n :: Nat) (os :: [(k,k1)])
-
-instance ( [a] ~ x
-         , Show a
-         ) => P (GuardsImplX n ('[] :: [(k,k1)])) x where
-  type PP (GuardsImplX n ('[] :: [(k,k1)])) x = x
-  eval _ opts as =
-    let msg0 = "Guards"
-        -- n :: Int = nat @n
-    in if not (null as) then errorInProgram $ "GuardsImplX base case has extra data " ++ show as
-       else pure $ mkNode opts (PresentT as) msg0 []
-
-instance (PP prt a ~ String
-        , P prt a
-        , KnownNat n
-        , GetLen ps
-        , P p a
-        , PP p a ~ Bool
-        , P (GuardsImplX n ps) [a]
-        , PP (GuardsImplX n ps) [a] ~ [a]
-        , Show a
-        , [a] ~ x
-        ) => P (GuardsImplX n ('(prt,p) ': ps)) x where
-  type PP (GuardsImplX n ('(prt,p) ': ps)) x = x
-  eval _ opts as' = do
-     let cpos = n-pos-1
-         msgbase1 = "Guard(" <> showIndex cpos <> ")"
-         msgbase2 = "Guards"
-         n :: Int = nat @n
-         pos = getLen @ps
-     case as' of
-         a:as -> do
-            pp <- evalBoolHide (Proxy @p) opts a
-            case getValueLR opts (msgbase1 <> " p failed") pp [] of
-                 Left e -> pure e
-                 Right False -> do
-                   qq <- eval (Proxy @prt) opts a -- only run prt when predicate is False
-                   pure $ case getValueLR opts (msgbase2 <> " False predicate and prt failed") qq [hh pp] of
-                      Left e -> e
-                      Right msgx -> mkNode opts (FailT msgx) (msgbase1 <> " failed [" <> msgx <> "]" <> " " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
-                 Right True -> do
-                   ss <- eval (Proxy @(GuardsImplX n ps)) opts as
-                   pure $ case getValueLR opts (msgbase1 <> " ok | rhs failed") ss [hh pp] of
-                     Left e -> e -- shortcut else we get too compounding errors with the pp tree being added each time!
-                     Right zs -> mkNode opts (PresentT (a:zs)) (msgbase1 <> " " <> showL opts a) [hh pp, hh ss]
-         _ -> errorInProgram "GuardsImplX n+1 case has no data"
-
-data GuardsDetail prt (ps :: [(k0,k1)])
-type GuardsDetailT prt (ps :: [(k0,k1)]) = GuardsDetailImpl (ToGuardsDetailT prt ps)
-
-instance P (GuardsDetailT prt ps) x => P (GuardsDetail prt ps) x where
-  type PP (GuardsDetail prt ps) x = PP (GuardsDetailT prt ps) x
-  eval _ = eval (Proxy @(GuardsDetailT prt ps))
-
-type family ToGuardsDetailT (prt :: k1) (os :: [(k2,k3)]) :: [(Type,k3)] where
-  ToGuardsDetailT prt '[ '(s,p) ] = '(PrintT prt '(s,Id), p) : '[]
-  ToGuardsDetailT prt ( '(s,p) ': ps) = '(PrintT prt '(s,Id), p) ': ToGuardsDetailT prt ps
-  ToGuardsDetailT prt '[] = GL.TypeError ('GL.Text "ToGuardsDetailT cannot be empty")
-
--- | leverages 'RepeatT' for repeating predicates (passthrough method)
---
--- >>> pz @(GuardsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,256]
--- FailT "id=3 must be between 0 and 255, found 256"
---
--- >>> pz @(GuardsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (Between 0 255 Id)) [121,33,7,44]
--- PresentT [121,33,7,44]
---
-data GuardsN prt (n :: Nat) p
-type GuardsNT prt (n :: Nat) p = Guards (ToGuardsT prt (RepeatT n p))
-
-instance ( x ~ [a]
-         , P (GuardsNT prt n p) x
-         ) => P (GuardsN prt n p) x where
-  type PP (GuardsN prt n p) x = PP (GuardsNT prt n p) x
-  eval _ = eval (Proxy @(GuardsNT prt n p))
-
--- | \'p\' is the predicate and on failure of the predicate runs \'prt\'
---
--- >>> pz @(Guard "expected > 3" (Gt 3)) 17
--- PresentT 17
---
--- >>> pz @(Guard "expected > 3" (Gt 3)) 1
--- FailT "expected > 3"
---
--- >>> pz @(Guard (PrintF "%d not > 3" Id) (Gt 3)) (-99)
--- FailT "-99 not > 3"
---
-data Guard prt p
-
-data ExitWhen prt p
-type ExitWhenT prt p = Guard prt (Not p)
-
-instance P (ExitWhenT prt p) x => P (ExitWhen prt p) x where
-  type PP (ExitWhen prt p) x = PP (ExitWhenT prt p) x
-  eval _ = eval (Proxy @(ExitWhenT prt p))
-
-instance (Show a
-        , P prt a
-        , PP prt a ~ String
-        , P p a
-        , PP p a ~ Bool
-        ) => P (Guard prt p) a where
-  type PP (Guard prt p) a = a
-  eval _ opts a = do
-    let msg0 = "Guard"
-    pp <- evalBool (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right False -> do
-        qq <- eval (Proxy @prt) opts a
-        pure $ case getValueLR opts (msg0 <> " Msg") qq [hh pp] of
-          Left e -> e
-          Right ee -> mkNode opts (FailT ee) (msg0 <> " | " <> showL opts a) (hh pp : [hh qq | isVerbose opts])
-      Right True -> pure $ mkNode opts (PresentT a) (msg0 <> "(ok)" <> " | " <> showL opts a) [hh pp]  -- dont show the guard message if successful
-
-
--- | similar to 'Guard' but uses the root message of the False predicate case as the failure message
---
--- most uses of GuardSimple can be replaced by a boolean predicate unless you require a failure message instead of true/false
---
--- >>> pz @(GuardSimple (Luhn Id)) [1..4]
--- FailT "(Luhn map=[4,6,2,2] sum=14 ret=4 | [1,2,3,4])"
---
--- >>> pl @(Luhn Id) [1..4]
--- False (Luhn map=[4,6,2,2] sum=14 ret=4 | [1,2,3,4])
--- FalseT
---
--- >>> pz @(GuardSimple (Luhn Id)) [1,2,3,0]
--- PresentT [1,2,3,0]
---
--- >>> pz @(GuardSimple (Len > 30)) [1,2,3,0]
--- FailT "(4 > 30)"
---
-data GuardSimple p
-
-instance (Show a
-        , P p a
-        , PP p a ~ Bool
-        ) => P (GuardSimple p) a where
-  type PP (GuardSimple p) a = a
-  eval _ opts a = do
-    let msg0 = "GuardSimple"
-    pp <- evalBool (Proxy @p) (subopts opts) a -- temporarily lift DZero to DLite so as not to lose the failure message
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right False ->
-        let msgx = topMessage pp
-        in mkNode opts (FailT msgx) (msg0 <> " | " <> showL opts a) [hh pp]
-      Right True ->
-        mkNode opts (PresentT a) (msg0 <> "(ok)" <> " | " <> showL opts a) [hh pp]
-
-
--- | just run the effect but skip the value
--- for example for use with Stdout so it doesnt interfere with the \'a\' on the rhs unless there is an failure
-data Skip p
-
-instance ( Show (PP p a)
-         , P p a
-         ) => P (Skip p) a where
-  type PP (Skip p) a = a
-  eval _ opts a = do
-    let msg0 = "Skip"
-    pp <- eval (Proxy @p) opts a
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p -> mkNode opts (PresentT a) (msg0 <> " " <> showL opts p) [hh pp]
-
-data p |> q
-type SkipLT p q = Skip p >> q
-infixr 1 |>
-
-instance P (SkipLT p q) x => P (p |> q) x where
-  type PP (p |> q) x = PP (SkipLT p q) x
-  eval _ = eval (Proxy @(SkipLT p q))
-
-data p >| q
-type SkipRT p q = p >> Skip q
-infixr 1 >|
-
-instance P (SkipRT p q) x => P (p >| q) x where
-  type PP (p >| q) x = PP (SkipRT p q) x
-  eval _ = eval (Proxy @(SkipRT p q))
-
-data p >|> q
-type SkipBothT p q = Skip p >> Skip q
-infixr 1 >|>
-
-instance P (SkipBothT p q) x => P (p >|> q) x where
-  type PP (p >|> q) x = PP (SkipBothT p q) x
-  eval _ = eval (Proxy @(SkipBothT p q))
-
--- advantage of (>>) over 'Do [k] is we can use different kinds for (>>) without having to wrap with 'W'
-
--- | This is composition for predicates
---
--- >>> pz @(Fst Id >> Succ (Id !! 0)) ([11,12],'x')
--- PresentT 12
---
--- >>> pz @(Len *** Succ Id >> ShowP (First (Pred Id))) ([11,12],'x')
--- PresentT "(1,'y')"
---
-data p >> q
-infixr 1 >>
-
-instance (Show (PP p a)
-        , Show (PP q (PP p a))
-        , P p a
-        , P q (PP p a)
-        ) => P (p >> q) a where
-  type PP (p >> q) a = PP q (PP p a)
-  eval _ opts a = do
-    let msg0 = "(>>)"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts "(>>) lhs failed" pp [] of
-      Left e -> pure e
-      Right p -> do
-        qq <- eval (Proxy @q) opts p
-        pure $ case getValueLR opts (show p <> " (>>) rhs failed") qq [hh pp] of
-          Left e -> e
-          Right q -> mkNode opts (_tBool qq) (lit01 opts msg0 q "" (topMessageEgregious qq)) [hh pp, hh qq]
-
--- bearbeiten! only used by >>
-topMessageEgregious :: TT a -> String
-topMessageEgregious pp = innermost (pp ^. tString)
-  where innermost = ('{':) . reverse . ('}':) . takeWhile (/='{') . dropWhile (=='}') . reverse
-
-data p << q
-type LeftArrowsT p q = q >> p
-infixr 1 <<
-
-instance P (LeftArrowsT p q) x => P (p << q) x where
-  type PP (p << q) x = PP (LeftArrowsT p q) x
-  eval _ = eval (Proxy @(LeftArrowsT p q))
-
-type p >>> q = p >> q
-infixl 1 >>>
-
--- | similar to 'Prelude.&&'
---
--- >>> pz @(Fst Id && Snd Id) (True, True)
--- TrueT
---
--- >>> pz @(Id > 15 && Id < 17) 16
--- TrueT
---
--- >>> pz @(Id > 15 && Id < 17) 30
--- FalseT
---
--- >>> pz @(Fst Id && (Length (Snd Id) >= 4)) (True,[11,12,13,14])
--- TrueT
---
--- >>> pz @(Fst Id && (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
--- FalseT
---
-data p && q
-infixr 3 &&
-
-instance (P p a
-        , P q a
-        , PP p a ~ Bool
-        , PP q a ~ Bool
-        ) => P (p && q) a where
-  type PP (p && q) a = Bool
-  eval _ opts a = do
-    let msg0 = "&&"
-    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let zz = case (p,q) of
-                  (True, True) -> ""
-                  (False, True) -> topMessage pp
-                  (True, False) -> topMessage qq
-                  (False, False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-        in mkNodeB opts (p&&q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh pp, hh qq]
-
--- | short circuit version of boolean And
---
--- >>> pl @(Id > 10 &&~ Failt _ "ss") 9
--- False (False &&~ _ | (9 > 10))
--- FalseT
---
--- >>> pl @(Id > 10 &&~ Id == 12) 11
--- False (True &&~ False | (11 == 12))
--- FalseT
---
--- >>> pl @(Id > 10 &&~ Id == 11) 11
--- True (True &&~ True)
--- TrueT
---
-data p &&~ q
-infixr 3 &&~
-
-instance (P p a
-        , P q a
-        , PP p a ~ Bool
-        , PP q a ~ Bool
-        ) => P (p &&~ q) a where
-  type PP (p &&~ q) a = Bool
-  eval _ opts a = do
-    let msg0 = "&&~"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right False ->
-        pure $ mkNodeB opts False ("False" <> " " <> msg0 <> " _" <> litVerbose opts " | " (topMessage pp)) [hh pp]
-      Right True -> do
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg0 qq [hh pp] of
-          Left e -> e
-          Right q ->
-            let zz = if q then ""
-                     else " | " <> topMessage qq
-            in mkNodeB opts q ("True" <> " " <> msg0 <> " " <> showL opts q <> litVerbose opts "" zz) [hh pp, hh qq]
-
--- | similar to 'Prelude.||'
---
--- >>> pz @(Fst Id || (Length (Snd Id) >= 4)) (False,[11,12,13,14])
--- TrueT
---
--- >>> pz @(Not (Fst Id) || (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
--- FalseT
---
-data p || q
-infixr 2 ||
-
-instance (P p a
-        , P q a
-        , PP p a ~ Bool
-        , PP q a ~ Bool
-        ) => P (p || q) a where
-  type PP (p || q) a = Bool
-  eval _ opts a = do
-    let msg0 = "||"
-    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let zz = case (p,q) of
-                  (False,False) -> " | " <> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-                  _ -> ""
-        in mkNodeB opts (p||q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> zz) [hh pp, hh qq]
-
--- | short circuit version of boolean Or
---
--- >>> pl @(Id > 10 ||~ Failt _ "ss") 11
--- True (True ||~ _ | (11 > 10))
--- TrueT
---
--- >>> pz @(Id > 10 ||~ Id == 9) 9
--- TrueT
---
--- >>> pl @(Id > 10 ||~ Id > 9) 9
--- False (False ||~ False | (9 > 10) ||~ (9 > 9))
--- FalseT
---
-data p ||~ q
-infixr 2 ||~
-
-instance (P p a
-        , P q a
-        , PP p a ~ Bool
-        , PP q a ~ Bool
-        ) => P (p ||~ q) a where
-  type PP (p ||~ q) a = Bool
-  eval _ opts a = do
-    let msg0 = "||~"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right False -> do
-        qq <- eval (Proxy @q) opts a
-        pure $ case getValueLR opts msg0 qq [hh pp] of
-          Left e -> e
-          Right q ->
-            let zz = if q then ""
-                     else " | " <> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-            in mkNodeB opts q ("False" <> " " <> msg0 <> " " <> showL opts q <> litVerbose opts "" zz) [hh pp, hh qq]
-      Right True ->
-        pure $ mkNodeB opts True ("True" <> " " <> msg0 <> " _" <> litVerbose opts " | " (topMessage pp)) [hh pp]
-
--- | implication
---
--- >>> pz @(Fst Id ~> (Length (Snd Id) >= 4)) (True,[11,12,13,14])
--- TrueT
---
--- >>> pz @(Fst Id ~> (Length (Snd Id) == 4)) (True,[12,11,12,13,14])
--- FalseT
---
--- >>> pz @(Fst Id ~> (Length (Snd Id) == 4)) (False,[12,11,12,13,14])
--- TrueT
---
--- >>> pz @(Fst Id ~> (Length (Snd Id) >= 4)) (False,[11,12,13,14])
--- TrueT
---
-data p ~> q
-infixr 1 ~>
-
-instance (P p a
-        , P q a
-        , PP p a ~ Bool
-        , PP q a ~ Bool
-        ) => P (p ~> q) a where
-  type PP (p ~> q) a = Bool
-  eval _ opts a = do
-    let msg0 = "~>"
-    lr <- runPQBool msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let zz = case (p,q) of
-                  (True,False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-                  _ -> ""
-        in mkNodeB opts (p~>q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh pp, hh qq]
-
--- | 'not' function
---
--- >>> pz @(Not Id) False
--- TrueT
---
--- >>> pz @(Not Id) True
--- FalseT
---
--- >>> pz @(Not (Fst Id)) (True,22)
--- FalseT
---
--- >>> pl @(Not (Lt 3)) 13
--- True (Not (13 < 3))
--- TrueT
---
-data Not p
-
-instance ( PP p x ~ Bool
-         , P p x
-         ) => P (Not p) x where
-  type PP (Not p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Not"
-    pp <- evalBool (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = not p
-        in mkNodeB opts b (msg0 <> litVerbose opts " " (topMessage pp)) [hh pp]
-
--- | 'id' function on a boolean
---
--- >>> pz @(IdBool Id) False
--- FalseT
---
--- >>> pz @(IdBool Id) True
--- TrueT
---
--- >>> pz @(IdBool (Fst Id)) (True,22)
--- TrueT
---
--- >>> pl @(IdBool (Lt 3)) 13
--- False (IdBool (13 < 3))
--- FalseT
---
-data IdBool p
-
-instance ( PP p x ~ Bool
-         , P p x
-         ) => P (IdBool p) x where
-  type PP (IdBool p) x = Bool
-  eval _ opts x = do
-    let msg0 = "IdBool"
-    pp <- evalBool (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = p
-        in mkNodeB opts b (msg0 <> litVerbose opts " " (topMessage pp)) [hh pp]
-
--- | similar to 'compare'
---
--- >>> pz @(Fst Id ==! Snd Id) (10,9)
--- PresentT GT
---
--- >>> pz @(14 % 3 ==! Fst Id -% Snd Id) (-10,7)
--- PresentT GT
---
--- >>> pz @(Fst Id ==! Snd Id) (10,11)
--- PresentT LT
---
--- >>> pz @(Snd Id ==! (Fst Id >> Snd Id >> Head Id)) (('x',[10,12,13]),10)
--- PresentT EQ
---
--- >>> pz @(Snd Id ==! Head (Snd (Fst Id))) (('x',[10,12,13]),10)
--- PresentT EQ
---
-
-data p ==! q
-infix 4 ==!
-
-type OrdP p q = p ==! q
-
-instance (Ord (PP p a)
-        , PP p a ~ PP q a
-        , P p a
-        , Show (PP q a)
-        , P q a
-        ) => P (p ==! q) a where
-  type PP (p ==! q) a = Ordering
-  eval _ opts a = do
-    let msg0 = "(==!)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = compare p q
-        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p <> " " <> prettyOrd d <> " " <> showL opts q) [hh pp, hh qq]
-
-data OrdA p
-
-instance P (OrdA' p p) x => P (OrdA p) x where
-  type PP (OrdA p) x = PP (OrdA' p p) x
-  eval _ = eval (Proxy @(OrdA' p p))
-
-data OrdA' p q
-type OrdAT' p q = (Fst Id >> p) ==! (Snd Id >> q)
-
-instance P (OrdAT' p q) x => P (OrdA' p q) x where
-  type PP (OrdA' p q) x = PP (OrdAT' p q) x
-  eval _ = eval (Proxy @(OrdAT' p q))
-
--- | compare two strings ignoring case
---
--- >>> pz @(Fst Id ===~ Snd Id) ("abC","aBc")
--- PresentT EQ
---
--- >>> pz @(Fst Id ===~ Snd Id) ("abC","DaBc")
--- PresentT LT
---
-type OrdI p q = p ===~ q
-data p ===~ q
-infix 4 ===~
-
-instance (PP p a ~ String
-        , PP p a ~ PP q a
-        , P p a
-        , P q a
-        ) => P (p ===~ q) a where
-  type PP (p ===~ q) a = Ordering
-  eval _ opts a = do
-    let msg0 = "(===~)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = on compare (map toLower) p q
-        in mkNode opts (PresentT d) (msg0 <> " " <> p <> " " <> prettyOrd d <> " " <> q) [hh pp, hh qq]
-
--- | compare two values using the given ordering \'o\'
---
--- >>> pl @(Lt 4) 123
--- False (123 < 4)
--- FalseT
---
--- >>> pl @(Lt 4) 1
--- True (1 < 4)
--- TrueT
---
--- >>> pl @(Negate 7 <..> 20) (-4)
--- True (-7 <= -4 <= 20)
--- TrueT
---
--- >>> pl @(Negate 7 <..> 20) 21
--- False (21 <= 20)
--- FalseT
---
-data Cmp (o :: OrderingP) p q
-
-instance (GetOrd o
-        , Ord (PP p a)
-        , Show (PP p a)
-        , PP p a ~ PP q a
-        , P p a
-        , P q a
-        ) => P (Cmp o p q) a where
-  type PP (Cmp o p q) a = Bool
-  eval _ opts a = do
-    let (sfn, fn) = getOrd @o
-    lr <- runPQ sfn (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = fn p q
-        in mkNodeB opts b (showL opts p <> " " <> sfn <> " " <> showL opts q) [hh pp, hh qq]
-
--- | compare two strings ignoring case using the given ordering \'o\'
-data CmpI (o :: OrderingP) p q
-
-instance (PP p a ~ String
-        , GetOrd o
-        , PP p a ~ PP q a
-        , P p a
-        , P q a
-        ) => P (CmpI o p q) a where
-  type PP (CmpI o p q) a = Bool
-  eval _ opts a = do
-    let (sfn, fn) = getOrd @o
-    lr <- runPQ sfn (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let b = on fn (map toLower) p q
-        in mkNodeB opts b ("CmpI " <> p <> " " <> sfn <> " " <> q) [hh pp, hh qq]
-
-
--- | similar to 'Control.Lens.itoList'
---
--- >>> pz @(IToList _ Id) ("aBc" :: String)
--- PresentT [(0,'a'),(1,'B'),(2,'c')]
---
-data IToList' t p
-
-instance (Show x
-        , P p x
-        , Typeable (PP t (PP p x))
-        , Show (PP t (PP p x))
-        , FoldableWithIndex (PP t (PP p x)) f
-        , PP p x ~ f a
-        , Show a
-        ) => P (IToList' t p) x where
-  type PP (IToList' t p) x = [(PP t (PP p x), ExtractAFromTA (PP p x))]
-  eval _ opts x = do
-    let msg0 = "IToList"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let b = itoList p
-            t = showT @(PP t (PP p x))
-        in mkNode opts (PresentT b) (msg0 <> "(" <> t <> ")" <> " " <> showL opts b <> showVerbose opts " | " x) [hh pp]
-
-data IToList (t :: Type) p
-type IToListT (t :: Type) p = IToList' (Hole t) p
-
-instance P (IToListT t p) x => P (IToList t p) x where
-  type PP (IToList t p) x = PP (IToListT t p) x
-  eval _ = eval (Proxy @(IToListT t p))
-
--- | similar to 'toList'
---
--- >>> pz @ToList ("aBc" :: String)
--- PresentT "aBc"
---
--- >>> pz @ToList (Just 14)
--- PresentT [14]
---
--- >>> pz @ToList Nothing
--- PresentT []
---
--- >>> pz @ToList (Left "xx")
--- PresentT []
---
--- >>> pz @ToList (These 12 "xx")
--- PresentT ["xx"]
---
-data ToList
-instance (Show (t a)
-        , Foldable t
-        ) => P ToList (t a) where
-  type PP ToList (t a) = [a]
-  eval _ opts as =
-    let msg0 = "ToList"
-        z = toList as
-    in pure $ mkNode opts (PresentT z) (msg0 <> showVerbose opts " " as) []
-
--- | similar to 'toList'
---
--- >>> pz @(ToList' Id) ("aBc" :: String)
--- PresentT "aBc"
---
--- >>> pz @(ToList' Id) (Just 14)
--- PresentT [14]
---
--- >>> pz @(ToList' Id) Nothing
--- PresentT []
---
--- >>> pz @(ToList' Id) (Left "xx")
--- PresentT []
---
--- >>> pz @(ToList' Id) (These 12 "xx")
--- PresentT ["xx"]
---
-data ToList' p
-
-instance (PP p x ~ t a
-        , P p x
-        , Show (t a)
-        , Foldable t
-        , Show a
-        ) => P (ToList' p) x where
-  type PP (ToList' p) x = [ExtractAFromTA (PP p x)] -- extra layer of indirection means pan (ToList' Id) "abc" won't work without setting the type of "abc" unlike ToList
-  eval _ opts x = do
-    let msg0 = "ToList'"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let hhs = [hh pp]
-            b = toList p
-        in mkNode opts (PresentT b) (show01 opts msg0 b p) hhs
-
--- | invokes 'GE.toList'
---
--- >>> pz @ToListExt (M.fromList [(1,'x'),(4,'y')])
--- PresentT [(1,'x'),(4,'y')]
---
--- >>> pz @ToListExt (T.pack "abc")
--- PresentT "abc"
---
-data ToListExt
-
-instance (Show l
-        , GE.IsList l
-        , Show (GE.Item l)
-        ) => P ToListExt l where
-  type PP ToListExt l = [GE.Item l]
-  eval _ opts as =
-    let msg0 = "ToListExt"
-        z = GE.toList as
-    in pure $ mkNode opts (PresentT z) (show01 opts msg0 z as) []
-
--- | invokes 'GE.fromList'
---
--- >>> import qualified Data.Set as Set
--- >>> run @('OMsg "Fred" ':# 'OLite ':# 'OColorOff) @(FromList (Set.Set Int) << '[2,1,5,5,2,5,2]) ()
--- Fred >>> Present fromList [1,2,5] ((>>) fromList [1,2,5] | {FromList fromList [1,2,5]})
--- PresentT (fromList [1,2,5])
---
-data FromList (t :: Type) -- doesnt work with OverloadedLists unless you cast to [a] explicitly
-
-instance (a ~ GE.Item t
-        , Show t
-        , GE.IsList t
-        , [a] ~ x
-        ) => P (FromList t) x where
-  type PP (FromList t) x = t
-  eval _ opts as =
-    let msg0 = "FromList"
-        z = GE.fromList (as :: [GE.Item t]) :: t
-    in pure $ mkNode opts (PresentT z) (msg0 <> " " <> showL opts z) []
-
--- | invokes 'GE.fromList'
---
--- requires the OverloadedLists extension
---
--- >>> :set -XOverloadedLists
--- >>> pz @(FromListExt (M.Map _ _)) [(4,"x"),(5,"dd")]
--- PresentT (fromList [(4,"x"),(5,"dd")])
---
-data FromListExt (t :: Type)
--- l ~ l' is key
-instance (Show l
-        , GE.IsList l
-        , l ~ l'
-        ) => P (FromListExt l') l where
-  type PP (FromListExt l') l = l'
-  eval _ opts as =
-    let msg0 = "FromListExt"
-        z = GE.fromList (GE.toList @l as)
-    in pure $ mkNode opts (PresentT z) (msg0 <> " " <> showL opts z) []
-
--- | predicate on 'These'
---
--- >>> pz @(IsThis Id) (This "aBc")
--- TrueT
---
--- >>> pz @(IsThis Id) (These 1 'a')
--- FalseT
---
--- >>> pz @(IsThese Id) (These 1 'a')
--- TrueT
---
--- >>> pl @(IsThat Id) (This 12)
--- False (IsThat | This 12)
--- FalseT
---
--- >>> pl @(IsThis Id) (This 12)
--- True (IsThis | This 12)
--- TrueT
---
--- >>> pl @(IsThese Id) (This 12)
--- False (IsThese | This 12)
--- FalseT
---
--- >>> pl @(IsThese Id) (These 'x' 12)
--- True (IsThese | These 'x' 12)
--- TrueT
---
-data IsTh (th :: These x y) p -- x y can be anything
-
--- trying to avoid show instance cos of ambiguities
-instance (PP p x ~ These a b
-        , P p x
-        , Show a
-        , Show b
-        , GetThese th
-        ) => P (IsTh (th :: These x1 x2) p) x where
-  type PP (IsTh th p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Is"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (t,f) = getThese @th
-            b = f p
-        in mkNodeB opts b (msg0 <> t <> showVerbose opts " | " p) [hh pp]
-
-data IsThis p
-type IsThisT p = IsTh ('This '()) p
-
-instance P (IsThisT p) x => P (IsThis p) x where
-  type PP (IsThis p) x = PP (IsThisT p) x
-  eval _ = evalBool (Proxy @(IsThisT p))
-
-data IsThat p
-type IsThatT p = IsTh ('That '()) p
-
-instance P (IsThatT p) x => P (IsThat p) x where
-  type PP (IsThat p) x = PP (IsThatT p) x
-  eval _ = evalBool (Proxy @(IsThatT p))
-
-data IsThese p
-type IsTheseT p = IsTh ('These '() '()) p
-
-instance P (IsTheseT p) x => P (IsThese p) x where
-  type PP (IsThese p) x = PP (IsTheseT p) x
-  eval _ = evalBool (Proxy @(IsTheseT p))
-
--- | similar to 'Data.These.these'
---
--- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (This 13)
--- PresentT 13
---
--- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (That "this is a long string")
--- PresentT 21
---
--- >>> pz @(TheseIn Id Len (Fst Id + Length (Snd Id))) (These 20 "somedata")
--- PresentT 28
---
--- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (That "this is a long string")
--- PresentT (Right "this is a long string")
---
--- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (These 1 "this is a long string")
--- PresentT (Right "this is a long string")
---
--- >>> pz @(TheseIn (MkLeft _ Id) (MkRight _ Id) (If (Fst Id > Length (Snd Id)) (MkLeft _ (Fst Id)) (MkRight _ (Snd Id)))) (These 100 "this is a long string")
--- PresentT (Left 100)
---
-data TheseIn p q r
-
-instance (Show a
-        , Show b
-        , Show (PP p a)
-        , P p a
-        , P q b
-        , P r (a,b)
-        , PP p a ~ PP q b
-        , PP p a ~ PP r (a,b)
-        , PP q b ~ PP r (a,b)
-         )  => P (TheseIn p q r) (These a b) where
-  type PP (TheseIn p q r) (These a b) = PP p a
-  eval _ opts th = do
-     let msg0 = "TheseIn"
-     case th of
-        This a -> do
-          let msg1 = "This "
-              msg2 = msg0 <> msg1
-          pp <- eval (Proxy @p) opts a
-          pure $ case getValueLR opts (msg2 <> "p failed") pp [] of
-               Left e -> e
-               Right c -> mkNode opts (PresentT c) (show01' opts msg0 c msg1 a) [hh pp]
-        That b -> do
-          let msg1 = "That "
-              msg2 = msg0 <> msg1
-          qq <- eval (Proxy @q) opts b
-          pure $ case getValueLR opts (msg2 <> "q failed") qq [] of
-               Left e -> e
-               Right c -> mkNode opts (PresentT c) (show01' opts msg0 c msg1 b) [hh qq]
-        These a b -> do
-          let msg1 = "These "
-              msg2 = msg0 <> msg1
-          rr <- eval (Proxy @r) opts (a,b)
-          pure $ case getValueLR opts (msg2 <> "r failed") rr [] of
-               Left e -> e
-               Right c -> mkNode opts (PresentT c) (show01 opts msg0 c (These a b)) [hh rr]
-
-data TheseId p q
-type TheseIdT p q = TheseIn '(I, p) '(q, I) I
-
-instance P (TheseIdT p q) x => P (TheseId p q) x where
-  type PP (TheseId p q) x = PP (TheseIdT p q) x
-  eval _ = eval (Proxy @(TheseIdT p q))
--- | creates an empty list of the given type
---
--- >>> pz @(Id :+ EmptyList _) 99
--- PresentT [99]
---
-data EmptyList' t
-
-instance P (EmptyList' t) x where
-  type PP (EmptyList' t) x = [PP t x]
-  eval _ opts _ =
-    pure $ mkNode opts (PresentT []) "EmptyList" []
-
-data EmptyList (t :: Type)
-type EmptyListT (t :: Type) = EmptyList' (Hole t)
-
-instance P (EmptyList t) x where
-  type PP (EmptyList t) x = PP (EmptyListT t) x
-  eval _ = eval (Proxy @(EmptyListT t))
-
--- | creates a singleton from a value
---
--- >>> pz @(Singleton (Char1 "aBc")) ()
--- PresentT "a"
---
--- >>> pz @(Singleton Id) False
--- PresentT [False]
---
--- >>> pz @(Singleton (Snd Id)) (False,"hello")
--- PresentT ["hello"]
---
-data Singleton p
-
-instance P p x => P (Singleton p) x where
-  type PP (Singleton p) x = [PP p x]
-  eval _ opts x = do
-    let msg0 = "Singleton"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p -> mkNode opts (PresentT [p]) msg0 [hh pp]
-
---type Singleton p = p :+ EmptyT [] p
-
--- | extracts the first character from a non empty 'Symbol'
---
--- >>> pz @(Char1 "aBc") ()
--- PresentT 'a'
---
-data Char1 (s :: Symbol)  -- gets the first char from the Symbol [requires that Symbol is not empty]
-instance ( KnownSymbol s
-         , GL.CmpSymbol s "" ~ 'GT
-         ) => P (Char1 s) a where
-  type PP (Char1 s) a = Char
-  eval _ opts _ =
-     case symb @s of
-       [] -> errorInProgram "Char1: found empty Symbol/string"
-       c:_ -> pure $ mkNode opts (PresentT c) ("Char1" <> " " <> showL opts c) []
-
--- | similar to 'Data.Align.align' thats pads with 'Data.These.This' or 'Data.These.That' if one list is shorter than the other
---
--- the key is that all information about both lists are preserved
---
--- >>> pz @(ZipThese (Fst Id) (Snd Id)) ("aBc", [1..5])
--- PresentT [These 'a' 1,These 'B' 2,These 'c' 3,That 4,That 5]
---
--- >>> pz @(ZipThese (Fst Id) (Snd Id)) ("aBcDeF", [1..3])
--- PresentT [These 'a' 1,These 'B' 2,These 'c' 3,This 'D',This 'e',This 'F']
---
--- >>> pz @(ZipThese Id Reverse) "aBcDeF"
--- PresentT [These 'a' 'F',These 'B' 'e',These 'c' 'D',These 'D' 'c',These 'e' 'B',These 'F' 'a']
---
--- >>> pz @(ZipThese Id '[]) "aBcDeF"
--- PresentT [This 'a',This 'B',This 'c',This 'D',This 'e',This 'F']
---
--- >>> pz @(ZipThese '[] Id) "aBcDeF"
--- PresentT [That 'a',That 'B',That 'c',That 'D',That 'e',That 'F']
---
--- >>> pz @(ZipThese '[] '[]) "aBcDeF"
--- PresentT []
---
-data ZipThese p q
-
-instance (PP p a ~ [x]
-        , PP q a ~ [y]
-        , P p a
-        , P q a
-        , Show x
-        , Show y
-        ) => P (ZipThese p q) a where
-  type PP (ZipThese p q) a = [These (ExtractAFromList (PP p a)) (ExtractAFromList (PP q a))]
-  eval _ opts a = do
-    let msg0 = "ZipThese"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> e
-          Right () ->
-            let d = simpleAlign p q
-            in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) hhs
-
-simpleAlign :: [a] -> [b] -> [These a b]
-simpleAlign as [] = map This as
-simpleAlign [] bs = map That bs
-simpleAlign (a:as) (b:bs) = These a b : simpleAlign as bs
-
-type family ExtractAFromTA (ta :: Type) :: Type where
-  ExtractAFromTA (t a) = a
-  ExtractAFromTA z = GL.TypeError (
-      'GL.Text "ExtractAFromTA: expected (t a) but found something else"
-      ':$$: 'GL.Text "t a = "
-      ':<>: 'GL.ShowType z)
-
--- todo: get ExtractAFromList failure to fire if wrong Type
--- | extract \'a\' from \'[a]\' which I need for type PP
-type family ExtractAFromList (as :: Type) :: Type where
-  ExtractAFromList [a] = a
-  ExtractAFromList z = GL.TypeError (
-      'GL.Text "ExtractAFromList: expected [a] but found something else"
-      ':$$: 'GL.Text "as = "
-      ':<>: 'GL.ShowType z)
-
-
--- | Zip two lists to their maximum length using padding if needed
---
--- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abc", [1..5])
--- PresentT [('a',1),('b',2),('c',3),('Z',4),('Z',5)]
---
--- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcdefg", [1..5])
--- PresentT [('a',1),('b',2),('c',3),('d',4),('e',5),('f',99),('g',99)]
---
--- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcde", [1..5])
--- PresentT [('a',1),('b',2),('c',3),('d',4),('e',5)]
---
--- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("", [1..5])
--- PresentT [('Z',1),('Z',2),('Z',3),('Z',4),('Z',5)]
---
--- >>> pz @(ZipPad (Char1 "Z") 99 (Fst Id) (Snd Id)) ("abcde", [])
--- PresentT [('a',99),('b',99),('c',99),('d',99),('e',99)]
---
-data ZipPad l r p q
-
-instance (PP l a ~ x
-        , PP r a ~ y
-        , P l a
-        , P r a
-        , PP p a ~ [x]
-        , PP q a ~ [y]
-        , P p a
-        , P q a
-        , Show x
-        , Show y
-        ) => P (ZipPad l r p q) a where
-  type PP (ZipPad l r p q) a = [(PP l a, PP r a)]
-  eval _ opts a = do
-    let msg0 = "ZipPad"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> pure e
-          Right () -> do
-            let lls = (length p,length q)
-            case uncurry compare lls of
-              LT -> do
-                ll <- eval (Proxy @l) opts a
-                pure $ case getValueLR opts (msg0 <> " l failed") ll hhs of
-                  Left e -> e
-                  Right l ->
-                    let d = zip (p ++ repeat l) q
-                    in mkNode opts (PresentT d) (show01' opts (msg0 <> " Left pad") d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh ll])
-              GT -> do
-                rr <- eval (Proxy @r) opts a
-                pure $ case getValueLR opts (msg0 <> " r failed") rr hhs of
-                  Left e -> e
-                  Right r ->
-                    let d =zip p (q ++ repeat r)
-                    in mkNode opts (PresentT d) (show01' opts (msg0 <> " Right pad") d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh rr])
-              EQ ->
-                let d = zip p q
-                in pure $ mkNode opts (PresentT d) (show01' opts (msg0 <> " No pad") d "p=" p <> showVerbose opts " | q=" q) hhs
-
-
--- | zip two lists padding the left hand side if needed
---
--- >>> pl @(ZipL 99 '[1,2,3] "abc") ()
--- Present [(1,'a'),(2,'b'),(3,'c')] (ZipL [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
--- PresentT [(1,'a'),(2,'b'),(3,'c')]
---
--- >>> pl @(ZipL 99 '[1,2] "abc") ()
--- Present [(1,'a'),(2,'b'),(99,'c')] (ZipL [(1,'a'),(2,'b'),(99,'c')] | p=[1,2] | q="abc")
--- PresentT [(1,'a'),(2,'b'),(99,'c')]
---
--- >>> pl @(ZipL 99 '[1] "abc") ()
--- Present [(1,'a'),(99,'b'),(99,'c')] (ZipL [(1,'a'),(99,'b'),(99,'c')] | p=[1] | q="abc")
--- PresentT [(1,'a'),(99,'b'),(99,'c')]
---
--- >>> pl @(ZipL 99 '[1,2,3] "ab") ()
--- Error ZipL(3,2) rhs would be truncated (p=[1,2,3] | q="ab")
--- FailT "ZipL(3,2) rhs would be truncated"
---
-data ZipL l p q
-instance (PP l a ~ x
-        , P l a
-        , PP p a ~ [x]
-        , PP q a ~ [y]
-        , P p a
-        , P q a
-        , Show x
-        , Show y
-        ) => P (ZipL l p q) a where
-  type PP (ZipL l p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
-  eval _ opts a = do
-    let msg0 = "ZipL"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> pure e
-          Right () -> do
-            let lls = (length p,length q)
-            case uncurry compare lls of
-              GT -> let msg1 = msg0 ++ show lls
-                    in pure $ mkNode opts (FailT (msg1 ++ " rhs would be truncated")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
-              _ -> do
-                     ll <- eval (Proxy @l) opts a
-                     pure $ case getValueLR opts (msg0 <> " l failed") ll hhs of
-                             Left e -> e
-                             Right l ->
-                               let d = zip (p ++ repeat l) q
-                               in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh ll])
-
--- | zip two lists padding the right hand side if needed
---
--- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "abc") ()
--- Present [(1,'a'),(2,'b'),(3,'c')] (ZipR [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
--- PresentT [(1,'a'),(2,'b'),(3,'c')]
---
--- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "ab") ()
--- Present [(1,'a'),(2,'b'),(3,'Z')] (ZipR [(1,'a'),(2,'b'),(3,'Z')] | p=[1,2,3] | q="ab")
--- PresentT [(1,'a'),(2,'b'),(3,'Z')]
---
--- >>> pl @(ZipR (Char1 "Z") '[1,2,3] "a") ()
--- Present [(1,'a'),(2,'Z'),(3,'Z')] (ZipR [(1,'a'),(2,'Z'),(3,'Z')] | p=[1,2,3] | q="a")
--- PresentT [(1,'a'),(2,'Z'),(3,'Z')]
---
--- >>> pl @(ZipR (Char1 "Z") '[1,2] "abc") ()
--- Error ZipR(2,3) rhs would be truncated (p=[1,2] | q="abc")
--- FailT "ZipR(2,3) rhs would be truncated"
---
-data ZipR r p q
-instance (PP r a ~ y
-        , P r a
-        , PP p a ~ [x]
-        , PP q a ~ [y]
-        , P p a
-        , P q a
-        , Show x
-        , Show y
-        ) => P (ZipR r p q) a where
-  type PP (ZipR r p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
-  eval _ opts a = do
-    let msg0 = "ZipR"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let hhs = [hh pp, hh qq]
-        case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> pure e
-          Right () -> do
-            let lls = (length p,length q)
-            case uncurry compare lls of
-              LT -> let msg1 = msg0 ++ show lls
-                    in pure $ mkNode opts (FailT (msg1 ++ " rhs would be truncated")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
-              _ -> do
-                     rr <- eval (Proxy @r) opts a
-                     pure $ case getValueLR opts (msg0 <> " l failed") rr hhs of
-                             Left e -> e
-                             Right r ->
-                               let d = zip p (q ++ repeat r)
-                               in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) (hhs ++ [hh rr])
-
--- | zip two lists with the same length
---
--- >>> pl @(Zip '[1,2,3] "abc") ()
--- Present [(1,'a'),(2,'b'),(3,'c')] (Zip [(1,'a'),(2,'b'),(3,'c')] | p=[1,2,3] | q="abc")
--- PresentT [(1,'a'),(2,'b'),(3,'c')]
---
--- >>> pl @(Zip '[1,2,3] "ab") ()
--- Error Zip(3,2) length mismatch (p=[1,2,3] | q="ab")
--- FailT "Zip(3,2) length mismatch"
---
--- >>> pl @(Zip '[1,2] "abc") ()
--- Error Zip(2,3) length mismatch (p=[1,2] | q="abc")
--- FailT "Zip(2,3) length mismatch"
---
-data Zip p q
-instance (PP p a ~ [x]
-        , PP q a ~ [y]
-        , P p a
-        , P q a
-        , Show x
-        , Show y
-        ) => P (Zip p q) a where
-  type PP (Zip p q) a = [(ExtractAFromList (PP p a), ExtractAFromList (PP q a))]
-  eval _ opts a = do
-    let msg0 = "Zip"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> e
-          Right () ->
-            let lls = (length p, length q)
-            in case uncurry compare lls of
-                 EQ -> let d = zip p q
-                       in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) hhs
-                 _ -> let msg1 = msg0 ++ show lls
-                      in mkNode opts (FailT (msg1 <> " length mismatch")) (showVerbose opts "p=" p <> showVerbose opts " | q=" q) hhs
-
--- | Luhn predicate check on last digit
---
--- >>> pz @(Luhn Id) [1,2,3,0]
--- TrueT
---
--- >>> pz @(Luhn Id) [1,2,3,4]
--- FalseT
---
--- >>> pz @(GuardSimple (Luhn Id)) [15,4,3,1,99]
--- FailT "(Luhn map=[90,2,3,8,6] sum=109 ret=9 | [15,4,3,1,99])"
---
--- >>> pl @(Luhn Id) [15,4,3,1,99]
--- False (Luhn map=[90,2,3,8,6] sum=109 ret=9 | [15,4,3,1,99])
--- FalseT
---
-data Luhn p
-
-instance (PP p x ~ [Int]
-        , P p x
-        ) => P (Luhn p) x where
-  type PP (Luhn p) x = Bool
-  eval _ opts x = do
-    let msg0 = "Luhn"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let xs = zipWith (*) (reverse p) (cycle [1,2])
-            ys = map (\w -> if w>=10 then w-9 else w) xs
-            z = sum ys
-            ret = z `mod` 10
-            hhs = [hh pp]
-        in if ret == 0 then mkNodeB opts True (msg0 <> " | " <> showL opts p) hhs
-           else mkNodeB opts False (msg0 <> " map=" <> showL opts ys <> " sum=" <> showL opts z <> " ret=" <> showL opts ret <> showVerbose opts " | " p) hhs
-
--- | Read a number using base 2 through a maximum of 36
---
--- >>> pz @(ReadBase Int 16 Id) "00feD"
--- PresentT 4077
---
--- >>> pz @(ReadBase Int 16 Id) "-ff"
--- PresentT (-255)
---
--- >>> pz @(ReadBase Int 2 Id) "10010011"
--- PresentT 147
---
--- >>> pz @(ReadBase Int 8 Id) "Abff"
--- FailT "invalid base 8"
---
--- >>> pl @(ReadBase Int 16 Id >> GuardSimple (Id > 0xffff) >> ShowBase 16 Id) "12344"
--- Present "12344" ((>>) "12344" | {ShowBase(16) 12344 | 74564})
--- PresentT "12344"
---
--- >>> :set -XBinaryLiterals
--- >>> pz @(ReadBase Int 16 Id >> GuardSimple (Id > 0b10011111) >> ShowBase 16 Id) "7f"
--- FailT "(127 > 159)"
---
-
--- supports negative numbers unlike readInt
-data ReadBase' t (n :: Nat) p
-
-instance (Typeable (PP t x)
-        , ZwischenT 2 36 n
-        , Show (PP t x)
-        , Num (PP t x)
-        , KnownNat n
-        , PP p x ~ String
-        , P p x
-        ) => P (ReadBase' t n p) x where
-  type PP (ReadBase' t n p) x = PP t x
-  eval _ opts x = do
-    let n = nat @n
-        xs = getValidBase n
-        msg0 = "ReadBase(" <> t <> "," <> show n <> ")"
-        t = showT @(PP t x)
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (ff,p1) = case p of
-                        '-':q -> (negate,q)
-                        _ -> (id,p)
-        in case Numeric.readInt (fromIntegral n)
-            ((`elem` xs) . toLower)
-            (fromJust . (`elemIndex` xs) . toLower)
-            p1 of
-             [(b,"")] -> mkNode opts (PresentT (ff b)) (msg0 <> " " <> showL opts (ff b) <> showVerbose opts " | " p) [hh pp]
-             o -> mkNode opts (FailT ("invalid base " <> show n)) (msg0 <> " as=" <> p <> " err=" <> showL opts o) [hh pp]
-
-data ReadBase (t :: Type) (n :: Nat) p
-type ReadBaseT (t :: Type) (n :: Nat) p = ReadBase' (Hole t) n p
-
-instance P (ReadBaseT t n p) x => P (ReadBase t n p) x where
-  type PP (ReadBase t n p) x = PP (ReadBaseT t n p) x
-  eval _ = eval (Proxy @(ReadBaseT t n p))
-
-getValidBase :: Int -> String
-getValidBase n =
-  let xs = ['0'..'9'] <> ['a'..'z']
-      len = length xs
-  in if n > len || n < 2 then errorInProgram $ "getValidBase: oops invalid base valid is 2 thru " ++ show len ++ " found " ++ show n
-     else take n xs
-
--- | Display a number at base 2 to 36, similar to 'showIntAtBase' but supports signed numbers
---
--- >>> pz @(ShowBase 16 Id) 4077
--- PresentT "fed"
---
--- >>> pz @(ShowBase 16 Id) (-255)
--- PresentT "-ff"
---
--- >>> pz @(ShowBase 2 Id) 147
--- PresentT "10010011"
---
--- >>> pz @(ShowBase 2 (Negate 147)) "whatever"
--- PresentT "-10010011"
---
-data ShowBase (n :: Nat) p
-
-instance (PP p x ~ a
-        , P p x
-        , Show a
-        , 2 GL.<= n
-        , n GL.<= 36
-        , KnownNat n
-        , Integral a
-        ) => P (ShowBase n p) x where
-  type PP (ShowBase n p) x = String
-  eval _ opts x = do
-    let n = nat @n
-        xs = getValidBase n
-        msg0 = "ShowBase(" <> show n <> ")"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let (ff,a') = if p < 0 then (('-':), abs p) else (id,p)
-            b = Numeric.showIntAtBase (fromIntegral n) (xs !!) a' ""
-        in mkNode opts (PresentT (ff b)) (msg0 <> " " <> litL opts (ff b) <> showVerbose opts " | " p) [hh pp]
-
--- | intercalate two lists
---
--- >>> pz @(Intercalate '["aB"] '["xxxx","yz","z","www","xyz"]) ()
--- PresentT ["xxxx","aB","yz","aB","z","aB","www","aB","xyz"]
---
--- >>> pz @(Intercalate '[W 99,Negate 98] Id) [1..5]
--- PresentT [1,99,-98,2,99,-98,3,99,-98,4,99,-98,5]
---
--- >>> pz @(Intercalate '[99,100] Id) [1..5]
---PresentT [1,99,100,2,99,100,3,99,100,4,99,100,5]
---
-data Intercalate p q
-
-instance (PP p x ~ [a]
-        , PP q x ~ PP p x
-        , P p x
-        , P q x
-        , Show a
-      ) => P (Intercalate p q) x where
-  type PP (Intercalate p q) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Intercalate"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-        in case chkSize opts msg0 p hhs <* chkSize opts msg0 q hhs of
-          Left e -> e
-          Right () ->
-            let d = intercalate p (map pure q)
-            in mkNode opts (PresentT d) (show01 opts msg0 d p <> showVerbose opts " | " q) hhs
-
--- | uses PrintF to format output for a single value
---
--- >>> pz @(PrintF "value=%03d" Id) 12
--- PresentT "value=012"
---
--- >>> pz @(PrintF "%s" (Fst Id)) ("abc",'x')
--- PresentT "abc"
---
--- >>> pz @(PrintF "%d" (Fst Id)) ("abc",'x')
--- FailT "PrintF (IO e=printf: bad formatting char 'd')"
---
-data PrintF s p
-
-instance (PrintfArg (PP p x)
-        , Show (PP p x)
-        , PP s x ~ String
-        , P s x
-        , P p x
-        ) => P (PrintF s p) x where
-  type PP (PrintF s p) x = String
-  eval _ opts x = do
-    let msg0 = "PrintF"
-    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
-    case lrx of
-      Left e -> pure e
-      Right (s,p,ss,pp) -> do
-        lr <- catchitNF @_ @E.SomeException (printf s p)
-        pure $ case lr of
-          Left e -> mkNode opts (FailT (msg0 <> " (" <> e <> ")")) (" " <> showL opts p <> " s=" <> s) [hh ss, hh pp]
-          Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> "" <> litL opts ret <> "]" <> showVerbose opts " | p=" p <> litVerbose opts " | s=" s) [hh ss, hh pp]
-
-type family GuardsT (ps :: [k]) where
-  GuardsT '[] = '[]
-  GuardsT (p ': ps) = Guard "fromGuardsT" p ': GuardsT ps
-
---type Guards' (ps :: [k]) = Para (GuardsT ps)
-
---type ToGuards (prt :: k) (os :: [k1]) = Proxy (Guards (ToGuardsT prt os))
-
-type family ToGuardsT (prt :: k) (os :: [k1]) :: [(k,k1)] where
-  ToGuardsT prt '[] = GL.TypeError ('GL.Text "ToGuardsT cannot be empty")
-  ToGuardsT prt '[p] = '(prt,p) : '[]
-  ToGuardsT prt (p ': ps) = '(prt,p) ': ToGuardsT prt ps
-
--- | runs values in parallel unlike 'Do' which is serial
---
--- >>> pz @(Para '[Id,Id + 1,Id * 4]) [10,20,30]
--- PresentT [10,21,120]
---
--- >>> pz @(Para '[Id,Id + 1,Id * 4]) [10,20,30,40]
--- FailT "Para:invalid length(4) expected 3"
---
-data ParaImpl (n :: Nat) (os :: [k])
-
-data Para (ps :: [k])
-
--- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out
-instance ([a] ~ x
-        , GetLen ps
-        , P (ParaImpl (LenT ps) ps) x
-        ) => P (Para ps) x where
-  type PP (Para ps) x = PP (ParaImpl (LenT ps) ps) x
-  eval _ opts as = do
-    let msg0 = "Para"
-        n = getLen @ps
-    if n /= length as then
-       let msg1 = msg0 <> badLength as n
-       in pure $ mkNode opts (FailT msg1) "" []
-    else eval (Proxy @(ParaImpl (LenT ps) ps)) opts as
-
--- only allow non empty lists -- might need [a] ~ x but it seems fine
-instance GL.TypeError ('GL.Text "ParaImpl '[] invalid: requires at least one value in the list")
-   => P (ParaImpl n ('[] :: [k])) x where
-  type PP (ParaImpl n ('[] :: [k])) x = Void
-  eval _ _ _ = errorInProgram "ParaImpl empty list"
-
-instance (Show (PP p a)
-        , KnownNat n
-        , Show a
-        , P p a
-        ) => P (ParaImpl n '[p]) [a] where
-  type PP (ParaImpl n '[p]) [a] = [PP p a]
-  eval _ opts as' = do
-    let msgbase0 = "Para"
-        msgbase1 = msgbase0 <> "(" <> show n <> ")"
-        n :: Int
-        n = nat @n
-    case as' of
-      [a] -> do
-        pp <- eval (Proxy @p) opts a
-        pure $ case getValueLR opts msgbase1 pp [] of
-          Left e -> e
-          -- showVerbose opts " " [b]  fails but using 'b' is ok and (b : []) also works!
-          -- GE.List problem
-          Right b -> mkNode opts (PresentT [b]) (msgbase1 <> " " <> showL opts [b] <> showVerbose opts " | " a) [hh pp]
-      _ -> errorInProgram $ "ParaImpl base case should have exactly one element but found " ++ show as'
-
-instance (KnownNat n
-        , GetLen ps
-        , P p a
-        , P (ParaImpl n (p1 ': ps)) [a]
-        , PP (ParaImpl n (p1 ': ps)) [a] ~ [PP p a]
-        , Show a
-        , Show (PP p a)
-        )
-     => P (ParaImpl n (p ': p1 ': ps)) [a] where
-  type PP (ParaImpl n (p ': p1 ': ps)) [a] = [PP p a]
-  eval _ opts as' = do
-     let cpos = n-pos-1
-         msgbase0 = msgbase2 <> "(" <> showIndex cpos <> " of " <> show n <> ")"
-         msgbase1 = msgbase2 <> "(" <> showIndex cpos <> ")"
-         msgbase2 = "Para"
-         n = nat @n
-         pos = 1 + getLen @ps -- cos p1!
-     case as' of
-       a:as -> do
-         pp <- eval (Proxy @p) opts a
-         case getValueLR opts msgbase0 pp [] of
-           Left e -> pure e
-           Right b -> do
-                        qq <- eval (Proxy @(ParaImpl n (p1 ': ps))) opts as
-                        pure $ case getValueLR opts (msgbase1 <> " rhs failed " <> show b) qq [hh pp] of
-                          Left e -> e
-                          Right bs -> mkNode opts (PresentT (b:bs)) (msgbase1 <> " " <> showL opts (b:bs) <> showVerbose opts " | " as') [hh pp, hh qq]
-       _ -> errorInProgram "ParaImpl n+1 case has no data left"
-
--- | leverages 'Para' for repeating predicates (passthrough method)
---
--- >>> pz @(ParaN 4 (Succ Id)) [1..4]
--- PresentT [2,3,4,5]
---
--- >>> pz @(ParaN 4 (Succ Id)) "azwxm"
--- FailT "Para:invalid length(5) expected 4"
---
--- >>> pz @(ParaN 4 (Succ Id)) "azwx"
--- PresentT "b{xy"
---
-data ParaN (n :: Nat) p
-
-instance ( P (ParaImpl (LenT (RepeatT n p)) (RepeatT n p)) x
-         , GetLen (RepeatT n p)
-         , x ~ [a]
-         ) => P (ParaN n p) x where
-  type PP (ParaN n p) x = PP (Para (RepeatT n p)) x
-  eval _ = eval (Proxy @(Para (RepeatT n p)))
-
--- | tries each predicate ps and on the first match runs the corresponding qs but if there is no match on ps then runs the fail case e
---
--- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 50
--- PresentT "50 is same50"
---
--- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 9
--- PresentT "9 is lt10"
---
--- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 3
--- PresentT "3 is lt4"
---
--- >>> pz @(Case (Failt _ "asdf") '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 99
--- FailT "asdf"
---
--- >>> pz @(Case (FailS "asdf" >> Snd Id >> Unproxy) '[Lt 4,Lt 10,Same 50] '[PrintF "%d is lt4" Id, PrintF "%d is lt10" Id, PrintF "%d is same50" Id] Id) 99
--- FailT "asdf"
---
--- >>> pz @(Case (Failt _ "x") '[Same "a",Same "b"] '["hey","there"] Id) "b"
--- PresentT "there"
---
--- >>> pz @(Case (Failt _ "x") '[Id == "a",Id == "b"] '["hey","there"] Id) "a"
--- PresentT "hey"
---
--- >>> pz @(Case (Failt _ "x") '[Same "a",Same "b"] '["hey","there"] Id) "c"
--- FailT "x"
---
-data CaseImpl (n :: Nat) (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
--- ps = conditions
--- qs = what to do [one to one
--- r = the value
--- e = otherwise  -- leave til later
-data Case (e :: k0) (ps :: [k]) (qs :: [k1]) (r :: k2)
-data Case' (ps :: [k]) (qs :: [k1]) (r :: k2)
-data Case'' s (ps :: [k]) (qs :: [k1]) (r :: k2)
-
-type CaseT' (ps :: [k]) (qs :: [k1]) (r :: k2) = Case (Snd Id >> Failp "Case:no match") ps qs r
-type CaseT'' s (ps :: [k]) (qs :: [k1]) (r :: k2) = Case (FailCaseT s) ps qs r -- eg s= PrintF "%s" (ShowP Id)
-
-instance P (CaseT'' s ps qs r) x => P (Case'' s ps qs r) x where
-  type PP (Case'' s ps qs r) x = PP (CaseT'' s ps qs r) x
-  eval _ = eval (Proxy @(CaseT'' s ps qs r))
-
-instance P (CaseT' ps qs r) x => P (Case' ps qs r) x where
-  type PP (Case' ps qs r) x = PP (CaseT' ps qs r) x
-  eval _ = eval (Proxy @(CaseT' ps qs r))
-
-type FailCaseT p = Fail (Snd Id >> Unproxy) (Fst Id >> p)
-
-type CaseImplT e ps qs r = CaseImpl (LenT ps) e ps qs r
-
--- passthru but adds the length of ps (replaces LenT in the type synonym to avoid type synonyms being expanded out
-instance (FailUnlessT (LenT ps DE.== LenT qs)
-                  ('GL.Text "lengths are not the same "
-                   ':<>: 'GL.ShowType (LenT ps)
-                   ':<>: 'GL.Text " vs "
-                   ':<>: 'GL.ShowType (LenT qs))
-        , P (CaseImplT e ps qs r) x
-        ) => P (Case e ps qs r) x where
-  type PP (Case e ps qs r) x = PP (CaseImplT e ps qs r) x
-  eval _ = eval (Proxy @(CaseImplT e ps qs r))
-
--- only allow non empty lists!
-instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: lhs requires at least one value in the list"))
-   => P (CaseImpl n e ('[] :: [k]) (q ': qs) r) x where
-  type PP (CaseImpl n e ('[] :: [k]) (q ': qs) r) x = Void
-  eval _ _ _ = errorInProgram "CaseImpl lhs empty"
-
-instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: rhs requires at least one value in the list"))
-   => P (CaseImpl n e (p ': ps) ('[] :: [k1]) r) x where
-  type PP (CaseImpl n e (p ': ps) ('[] :: [k1]) r) x = Void
-  eval _ _ _ = errorInProgram "CaseImpl rhs empty"
-
-instance (GL.TypeError ('GL.Text "CaseImpl '[] invalid: lists are both empty"))
-   => P (CaseImpl n e ('[] :: [k]) ('[] :: [k1]) r) x where
-  type PP (CaseImpl n e ('[] :: [k]) ('[] :: [k1]) r) x = Void
-  eval _ _ _ = errorInProgram "CaseImpl both lists empty"
-
-instance (P r x
-        , P q (PP r x)
-        , Show (PP q (PP r x))
-        , P p (PP r x)
-        , PP p (PP r x) ~ Bool
-        , KnownNat n
-        , Show (PP r x)
-        , P e (PP r x, Proxy (PP q (PP r x)))
-        , PP e (PP r x, Proxy (PP q (PP r x))) ~ PP q (PP r x)
-        ) => P (CaseImpl n e '[p] '[q] r) x where
-  type PP (CaseImpl n e '[p] '[q] r) x = PP q (PP r x)
-  eval _ opts z = do
-    let msgbase0 = "Case(" <> show n <> ")"
-        n :: Int = nat @n
-    rr <- eval (Proxy @r) opts z
-    case getValueLR opts msgbase0 rr [] of
-      Left e -> pure e
-      Right a -> do
-        pp <- evalBool (Proxy @p) opts a
-        case getValueLR opts msgbase0 pp [hh rr] of
-          Left e -> pure e
-          Right True -> do
-            qq <- eval (Proxy @q) opts a
-            pure $ case getValueLR opts msgbase0 qq [hh rr, hh pp] of
-              Left e -> e
-              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) (hh rr : hh pp : [hh qq | isVerbose opts])
-          Right False -> do
-            ee <- eval (Proxy @e) opts (a, Proxy @(PP q (PP r x)))
-            pure $ case getValueLR opts (msgbase0 <> "  otherwise failed") ee [hh rr, hh pp] of
-              Left e -> e
-              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) [hh rr, hh pp, hh ee]
-
-instance (KnownNat n
-        , GetLen ps
-        , P r x
-        , P p (PP r x)
-        , P q (PP r x)
-        , PP p (PP r x) ~ Bool
-        , Show (PP q (PP r x))
-        , Show (PP r x)
-        , P (CaseImpl n e (p1 ': ps) (q1 ': qs) r) x
-        , PP (CaseImpl n e (p1 ': ps) (q1 ': qs) r) x ~ PP q (PP r x)
-        )
-     => P (CaseImpl n e (p ': p1 ': ps) (q ': q1 ': qs) r) x where
-  type PP (CaseImpl n e (p ': p1 ': ps) (q ': q1 ': qs) r) x = PP q (PP r x)
-  eval _ opts z = do
-    let cpos = n-pos-1
-        msgbase0 = msgbase2 <> "(" <> showIndex cpos <> " of " <> show n <> ")"
-        msgbase1 = msgbase2 <> "(" <> showIndex cpos <> ")"
-        msgbase2 = "Case"
-        n = nat @n
-        pos = 1 + getLen @ps -- cos p1!
-    rr <- eval (Proxy @r) opts z
-    case getValueLR opts msgbase0 rr [] of
-      Left e -> pure e
-      Right a -> do
-        pp <- evalBool (Proxy @p) opts a
-        case getValueLR opts msgbase0 pp [hh rr] of
-          Left e -> pure e
-          Right True -> do
-            qq <- eval (Proxy @q) opts a
-            pure $ case getValueLR opts msgbase0 qq [hh pp, hh rr] of
-              Left e -> e
-              Right b -> mkNode opts (PresentT b) (show01 opts msgbase0 b a) (hh rr : hh pp : [hh qq | isVerbose opts])
-          Right False -> do
-            ww <- eval (Proxy @(CaseImpl n e (p1 ': ps) (q1 ': qs) r)) opts z
-            pure $ case getValueLR opts (msgbase1 <> " failed rhs") ww [hh rr, hh pp] of
-              Left e -> e
-              Right b -> mkNode opts (PresentT b) (show01 opts msgbase1 b a) [hh rr, hh pp, hh ww]
-
--- | similar to 'sequenceA'
---
--- >>> pz @Sequence [Just 10, Just 20, Just 30]
--- PresentT (Just [10,20,30])
---
--- >>> pz @Sequence [Just 10, Just 20, Just 30, Nothing, Just 40]
--- PresentT Nothing
---
-data Sequence
-
-instance (Show (f (t a))
-        , Show (t (f a))
-        , Traversable t
-        , Applicative f
-        ) => P Sequence (t (f a)) where
-  type PP Sequence (t (f a)) = f (t a)
-  eval _ opts tfa =
-     let d = sequenceA tfa
-     in pure $ mkNode opts (PresentT d) ("Sequence" <> " " <> showL opts d <> showVerbose opts " | " tfa) []
-
-data Traverse p q
-type TraverseT p q = Map p q >> Sequence
-
-instance P (TraverseT p q) x => P (Traverse p q) x where
-  type PP (Traverse p q) x = PP (TraverseT p q) x
-  eval _ = eval (Proxy @(TraverseT p q))
-
--- | similar to 'readFile'
---
--- >>> pz @(ReadFile "LICENSE" >> 'Just Id >> Len > 0) ()
--- TrueT
---
--- >>> pz @(FileExists "xyzzy") ()
--- FalseT
---
-data ReadFile p
-
-data FileExists p
-type FileExistsT p = IsJust (ReadFile p)
-
-instance P (FileExistsT p) x => P (FileExists p) x where
-  type PP (FileExists p) x = PP (FileExistsT p) x
-  eval _ = evalBool (Proxy @(FileExistsT p))
-
-instance ( PP p x ~ String
-         , P p x
-         ) => P (ReadFile p) x where
-  type PP (ReadFile p) x = Maybe String
-  eval _ opts x = do
-    let msg0 = "ReadFile"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        let msg1 = msg0 <> "[" <> p <> "]"
-        mb <- runIO $ do
-                b <- doesFileExist p
-                if b then Just <$> readFile p
-                else pure Nothing
-        pure $ case mb of
-          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
-          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
-          Just (Just b) -> mkNode opts (PresentT (Just b)) (msg1 <> " len=" <> show (length b) <> " Just " <> litL opts b) [hh pp]
-
--- | does the directory exists
---
--- >>> pz @(DirExists ".") ()
--- TrueT
---
-data ReadDir p
-data DirExists p
-type DirExistsT p = IsJust (ReadDir p)
-
-instance P (DirExistsT p) x => P (DirExists p) x where
-  type PP (DirExists p) x = PP (DirExistsT p) x
-  eval _ = evalBool (Proxy @(DirExistsT p))
-
-
-instance ( PP p x ~ String
-         , P p x
-         ) => P (ReadDir p) x where
-  type PP (ReadDir p) x = Maybe [FilePath]
-  eval _ opts x = do
-    let msg0 = "ReadDir"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        let msg1 = msg0 <> "[" <> p <> "]"
-        mb <- runIO $ do
-                b <- doesDirectoryExist p
-                if b then Just <$> listDirectory p
-                else pure Nothing
-        pure $ case mb of
-          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
-          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
-          Just (Just b) -> mkNode opts (PresentT (Just b)) (msg1 <> " len=" <> show (length b) <> " Just " <> showL opts b) [hh pp]
-
--- | read an environment variable
---
--- >>> pz @(ReadEnv "PATH" >> 'Just Id >> 'True) ()
--- TrueT
---
-data ReadEnv p
-
-instance ( PP p x ~ String
-         , P p x
-         ) => P (ReadEnv p) x where
-  type PP (ReadEnv p) x = Maybe String
-  eval _ opts x = do
-    let msg0 = "ReadEnv"
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        let msg1 = msg0 <> "[" <> p <> "]"
-        mb <- runIO $ lookupEnv p
-        pure $ case mb of
-          Nothing -> mkNode opts (FailT msg1) "" [hh pp]
-          Just Nothing -> mkNode opts (PresentT Nothing) (msg1 <> " does not exist") [hh pp]
-          Just (Just v) -> mkNode opts (PresentT (Just v)) (msg1 <> " " <> litL opts v) [hh pp]
-
--- | read all the environment variables as key value pairs
-data ReadEnvAll
-
-instance P ReadEnvAll a where
-  type PP ReadEnvAll a = [(String,String)]
-  eval _ opts _ = do
-    let msg0 = "ReadEnvAll"
-    mb <- runIO getEnvironment
-    pure $ case mb of
-      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
-      Just v -> mkNode opts (PresentT v) (msg0 <> " count=" <> show (length v)) []
-
--- | get the current time using 'UTCTime'
-data TimeUtc
-
-instance P TimeUtc a where
-  type PP TimeUtc a = UTCTime
-  eval _ opts _a = do
-    let msg0 = "TimeUtc"
-    mb <- runIO getCurrentTime
-    pure $ case mb of
-      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
-      Just v -> mkNode opts (PresentT v) (msg0 <> " " <> showL opts v) []
-
--- | get the current time using 'ZonedTime'
-data TimeZt
-
-instance P TimeZt a where
-  type PP TimeZt a = ZonedTime
-  eval _ opts _a = do
-    let msg0 = "TimeZt"
-    mb <- runIO getZonedTime
-    pure $ case mb of
-      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
-      Just v -> mkNode opts (PresentT v) (msg0 <> " " <> showL opts v) []
-
-data FHandle s = FStdout | FStderr | FOther !s !WFMode deriving Show
-
-class GetFHandle (x :: FHandle Symbol) where getFHandle :: FHandle String
-instance GetFHandle 'FStdout where getFHandle = FStdout
-instance GetFHandle 'FStderr where getFHandle = FStderr
-instance (GetMode w, KnownSymbol s) => GetFHandle ('FOther s w) where getFHandle = FOther (symb @s) (getMode @w)
-
-data WFMode = WFAppend | WFWrite | WFWriteForce deriving (Show,Eq)
-
-class GetMode (x :: WFMode) where getMode :: WFMode
-instance GetMode 'WFAppend where getMode = WFAppend
-instance GetMode 'WFWriteForce where getMode = WFWriteForce
-instance GetMode 'WFWrite where getMode = WFWrite
-
-data WriteFileImpl (hh :: FHandle Symbol) p
-
--- | append to a file
-data AppendFile (s :: Symbol) p
-type AppendFileT (s :: Symbol) p = WriteFileImpl ('FOther s 'WFAppend) p
-
-instance P (AppendFileT s p) x => P (AppendFile s p) x where
-  type PP (AppendFile s p) x = PP (AppendFileT s p) x
-  eval _ = eval (Proxy @(AppendFileT s p))
-
-
--- | write to file, overwriting if needed
-data WriteFile' (s :: Symbol) p
-type WriteFileT' (s :: Symbol) p = WriteFileImpl ('FOther s 'WFWriteForce) p
-
-instance P (WriteFileT' s p) x => P (WriteFile' s p) x where
-  type PP (WriteFile' s p) x = PP (WriteFileT' s p) x
-  eval _ = eval (Proxy @(WriteFileT' s p))
-
--- | write to file, without overwriting
-data WriteFile (s :: Symbol) p
-type WriteFileT (s :: Symbol) p = WriteFileImpl ('FOther s 'WFWrite) p
-
-instance P (WriteFileT s p) x => P (WriteFile s p) x where
-  type PP (WriteFile s p) x = PP (WriteFileT s p) x
-  eval _ = eval (Proxy @(WriteFileT s p))
-
--- | write a string value to stdout
-data Stdout p
-type StdoutT p = WriteFileImpl 'FStdout p
-
-instance P (StdoutT p) x => P (Stdout p) x where
-  type PP (Stdout p) x = PP (StdoutT p) x
-  eval _ = eval (Proxy @(StdoutT p))
-
--- | write a string value to stderr
-data Stderr p
-type StderrT p = WriteFileImpl 'FStderr p
-
-instance P (StderrT p) x => P (Stderr p) x where
-  type PP (Stderr p) x = PP (StderrT p) x
-  eval _ = eval (Proxy @(StderrT p))
-
-instance (GetFHandle fh
-        , P p a
-        , PP p a ~ String
-        ) => P (WriteFileImpl fh p) a where
-  type PP (WriteFileImpl fh p) a = ()
-  eval _ opts a = do
-    let fh = getFHandle @fh
-        msg0 = case fh of
-                      FStdout -> "Stdout"
-                      FStderr -> "Stderr"
-                      FOther s w -> (<>("[" <> s <> "]")) $ case w of
-                         WFAppend -> "AppendFile"
-                         WFWrite -> "WriteFile"
-                         WFWriteForce -> "WriteFile'"
-    pp <- eval (Proxy @p) opts a
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right ss -> do
-          mb <- runIO $ case fh of
-                  FStdout -> fmap (left show) $ E.try @E.SomeException $ putStr ss
-                  FStderr -> fmap (left show) $ E.try @E.SomeException $ putStr ss
-                  FOther s w -> do
-                     b <- doesFileExist s
-                     if b && w == WFWrite then pure $ Left $ "file [" <> s <> "] already exists"
-                     else do
-                            let md = case w of
-                                   WFAppend -> AppendMode
-                                   _ -> WriteMode
-                            fmap (left show) $ E.try @E.SomeException $ withFile s md (`hPutStr` ss)
-          pure $ case mb of
-            Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" [hh pp]
-            Just (Left e) -> mkNode opts (FailT e) (msg0 <> " " <> e) [hh pp]
-            Just (Right ()) -> mkNode opts (PresentT ()) msg0 [hh pp]
-
--- | read in a value of a given type from stdin with a prompt: similar to 'System.IO.readIO'
-type ReadIO (t :: Type) = ReadIO' t "Enter value"
-type ReadIO' (t :: Type) s = Stdout (s <> ":") >> Stdin >> ReadP t Id
--- eg pa @(ReadIO Int + ReadIO Int) ()
-
--- | read a value from stdin
-data Stdin
-
-instance P Stdin x where
-  type PP Stdin x = String
-  eval _ opts _x = do
-    let msg0 = "Stdin"
-    mb <- runIO $ do
-                      lr <- E.try getLine
-                      pure $ case lr of
-                        Left (e :: E.SomeException) -> Left $ show e
-                        Right ss -> Right ss
-    pure $ case mb of
-      Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" []
-      Just (Left e) -> mkNode opts (FailT e) (msg0 <> " " <> e) []
-      Just (Right ss) -> mkNode opts (PresentT ss) (msg0 <> "[" <> litVerbose opts "" ss <> "]") []
-
---type Just' = JustFail "expected Just" Id
---type Nothing' = Guard "expected Nothing" IsNothing
-
--- | similar to 'isInfixOf' 'isPrefixOf' 'isSuffixOf' for strings only.
---
--- The \'I\' suffixed versions work are case insensitive.
---
--- >>> pz @(IsInfixI "abc" "axAbCd") ()
--- TrueT
---
--- >>> pz @(IsPrefixI "abc" "aBcbCd") ()
--- TrueT
---
--- >>> pz @(IsPrefix "abc" "aBcbCd") ()
--- FalseT
---
--- >>> pz @(IsSuffix "bCd" "aBcbCd") ()
--- TrueT
---
-data IsFixImpl (cmp :: Ordering) (ignore :: Bool) p q
-
-instance (GetBool ignore
-        , P p x
-        , P q x
-        , PP p x ~ String
-        , PP q x ~ String
-        , GetOrdering cmp
-        ) => P (IsFixImpl cmp ignore p q) x where
-  type PP (IsFixImpl cmp ignore p q) x = Bool
-  eval _ opts x = do
-    let cmp = getOrdering @cmp
-        ignore = getBool @ignore
-        lwr = if ignore then map toLower else id
-        (ff,msg0) = case cmp of
-                    LT -> (isPrefixOf, "IsPrefix")
-                    EQ -> (isInfixOf, "IsInfix")
-                    GT -> (isSuffixOf, "IsSuffix")
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-        Left e -> pure e
-        Right s0 -> do
-          let msg1 = msg0 <> (if ignore then "I" else "") <> "(" <> s0 <> ")"
-          qq <- eval (Proxy @q) opts x
-          pure $ case getValueLR opts (msg1 <> " q failed") qq [hh pp] of
-            Left e -> e
-            Right s1 -> mkNodeB opts (on ff lwr s0 s1) (msg1 <> " " <> litL opts s1) [hh pp, hh qq]
-
-data IsPrefix p q
-type IsPrefixT p q = IsFixImpl 'LT 'False p q
-
-instance P (IsPrefixT p q) x => P (IsPrefix p q) x where
-  type PP (IsPrefix p q) x = PP (IsPrefixT p q) x
-  eval _ = evalBool (Proxy @(IsPrefixT p q))
-
-data IsInfix p q
-type IsInfixT p q = IsFixImpl 'EQ 'False p q
-
-instance P (IsInfixT p q) x => P (IsInfix p q) x where
-  type PP (IsInfix p q) x = PP (IsInfixT p q) x
-  eval _ = evalBool (Proxy @(IsInfixT p q))
-
-data IsSuffix p q
-type IsSuffixT p q = IsFixImpl 'GT 'False p q
-
-instance P (IsSuffixT p q) x => P (IsSuffix p q) x where
-  type PP (IsSuffix p q) x = PP (IsSuffixT p q) x
-  eval _ = evalBool (Proxy @(IsSuffixT p q))
-
-data IsPrefixI p q
-type IsPrefixIT p q = IsFixImpl 'LT 'True p q
-
-instance P (IsPrefixIT p q) x => P (IsPrefixI p q) x where
-  type PP (IsPrefixI p q) x = PP (IsPrefixIT p q) x
-  eval _ = evalBool (Proxy @(IsPrefixIT p q))
-
-data IsInfixI p q
-type IsInfixIT p q = IsFixImpl 'EQ 'True p q
-
-instance P (IsInfixIT p q) x => P (IsInfixI p q) x where
-  type PP (IsInfixI p q) x = PP (IsInfixIT p q) x
-  eval _ = evalBool (Proxy @(IsInfixIT p q))
-
-data IsSuffixI p q
-type IsSuffixIT p q = IsFixImpl 'GT 'True p q
-
-instance P (IsSuffixIT p q) x => P (IsSuffixI p q) x where
-  type PP (IsSuffixI p q) x = PP (IsSuffixIT p q) x
-  eval _ = evalBool (Proxy @(IsSuffixIT p q))
-
--- | similar to 'SG.<>'
---
--- >>> pz @(Fst Id <> Snd Id) ("abc","def")
--- PresentT "abcdef"
---
--- >>> pz @("abcd" <> "ef" <> Id) "ghi"
--- PresentT "abcdefghi"
---
--- >>> pz @("abcd" <> "ef" <> Id) "ghi"
--- PresentT "abcdefghi"
---
--- >>> pz @(Wrap (SG.Sum _) Id <> FromInteger _ 10) 13
--- PresentT (Sum {getSum = 23})
---
--- >>> pz @(Wrap (SG.Product _) Id <> FromInteger _ 10) 13
--- PresentT (Product {getProduct = 130})
---
--- >>> pz @('(FromInteger _ 10,"def") <> Id) (SG.Sum 12, "_XYZ")
--- PresentT (Sum {getSum = 22},"def_XYZ")
---
--- >>> pz @(SapA' (SG.Max _)) (10,12)
--- PresentT (Max {getMax = 12})
---
--- >>> pz @(SapA' (SG.Sum _)) (10,12)
--- PresentT (Sum {getSum = 22})
---
-data p <> q
-infixr 6 <>
-
-instance (Semigroup (PP p x)
-        , PP p x ~ PP q x
-        , P p x
-        , Show (PP q x)
-        ,P q x
-        ) => P (p <> q) x where
-  type PP (p <> q) x = PP p x
-  eval _ opts x = do
-    let msg0 = "<>"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = p <> q
-        in mkNode opts (PresentT d) (showL opts p <> " <> " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
-
-data SapA' (t :: Type)
-type SapAT' (t :: Type) = Wrap t (Fst Id) <> Wrap t (Snd Id)
-
-instance P (SapAT' t) x => P (SapA' t) x where
-  type PP (SapA' t) x = PP (SapAT' t) x
-  eval _ = eval (Proxy @(SapAT' t))
-
-data SapA
-type SapAT = Fst Id <> Snd Id
-
-instance P SapAT x => P SapA x where
-  type PP SapA x = PP SapAT x
-  eval _ = eval (Proxy @SapAT)
-
--- | uses inductive tuples to replace variable arguments
---
-class PrintC x where
-  prtC :: (PrintfArg a, PrintfType r) => String -> (a,x) -> r
-instance PrintC () where
-  prtC s (a,()) = printf s a
-instance ( PrintfArg a
-         , PrintC rs
-         ) => PrintC (a,rs) where
-  prtC s (a,rs) = prtC s rs a
-
--- | print for flat n-tuples of size two or larger
---
--- >>> pl @(PrintT "%d %s %s %s" '(Fst Id, Snd Id, Snd Id,Snd Id)) (10,"Asdf")
--- Present "10 Asdf Asdf Asdf" (PrintT [10 Asdf Asdf Asdf] | s=%d %s %s %s)
--- PresentT "10 Asdf Asdf Asdf"
---
--- >>> pl @(PrintT "%c %d %s" Id) ('x', 10,"Asdf")
--- Present "x 10 Asdf" (PrintT [x 10 Asdf] | s=%c %d %s)
--- PresentT "x 10 Asdf"
---
--- >>> pz @(PrintT "fst=%s snd=%03d" Id) ("ab",123)
--- PresentT "fst=ab snd=123"
---
--- >>> pz @(PrintT "fst=%s snd=%03d thd=%s" Id) ("ab",123,"xx")
--- PresentT "fst=ab snd=123 thd=xx"
---
--- >>> pl @(PrintT "%s %d %c %s" '(W "xyz", Fst Id, Snd Id, Thd Id)) (123,'x',"ab")
--- Present "xyz 123 x ab" (PrintT [xyz 123 x ab] | s=%s %d %c %s)
--- PresentT "xyz 123 x ab"
---
--- >>> pl @(PrintT "%d %c %s" Id) (123,'x')
--- Error PrintT(IO e=printf: argument list ended prematurely) (PrintT %d %c %s)
--- FailT "PrintT(IO e=printf: argument list ended prematurely)"
---
--- >>> pl @(PrintT "%d %c %s" Id) (123,'x',"abc",11)
--- Error PrintT(IO e=printf: formatting string ended prematurely) (PrintT %d %c %s)
--- FailT "PrintT(IO e=printf: formatting string ended prematurely)"
---
-data PrintT s p
-instance (PrintC bs
-        , (b,bs) ~ InductTupleP y
-        , InductTupleC y
-        , PrintfArg b
-        , PP s x ~ String
-        , PP p x ~ y
-        , P s x
-        , P p x
-        , CheckT (PP p x) ~ 'True
-        ) => P (PrintT s p) x where
-  type PP (PrintT s p) x = String
-  eval _ opts x = do
-    let msg0 = "PrintT"
-    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
-    case lrx of
-      Left e -> pure e
-      Right (s,y,ss,pp) -> do
-        let hhs = [hh ss, hh pp]
-        lr <- catchitNF @_ @E.SomeException (prtC @bs s (inductTupleC y))
-        pure $ case lr of
-          Left e -> mkNode opts (FailT (msg0 <> "(" <> e <> ")")) (msg0 <> " " <> s) hhs
-          Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> litL opts ret <> "]" <> " | s=" <> litL opts s) hhs
-
--- | print for lists  -- use 'PrintT' as it is safer than 'PrintL'
---
--- >>> pl @(PrintL 4 "%s %s %s %s" '[W "xyz", ShowP (Fst Id), ShowP (Snd Id), Thd Id]) (123,'x',"ab")
--- Present "xyz 123 'x' ab" (PrintL(4) [xyz 123 'x' ab] | s=%s %s %s %s)
--- PresentT "xyz 123 'x' ab"
---
--- >>> pz @(PrintL 1 "%05d" '[Id]) 123  -- tick is required for a one element list (use 'PrintF')
--- PresentT "00123"
---
--- >>> pz @(PrintL 2 "%d %05d" [Fst Id,Snd Id]) (29,123)
--- PresentT "29 00123"
---
--- >>> pl @(PrintL 3 "first=%d second=%d third=%d" Id) [10,11,12]
--- Present "first=10 second=11 third=12" (PrintL(3) [first=10 second=11 third=12] | s=first=%d second=%d third=%d)
--- PresentT "first=10 second=11 third=12"
---
--- >>> pl @(PrintL 2 "first=%d second=%d third=%d" Id) [10,11,12]
--- Error PrintL(2) arg count=3 (wrong length 3)
--- FailT "PrintL(2) arg count=3"
---
--- >>> pl @(PrintL 4 "first=%d second=%d third=%d" Id) [10,11,12]
--- Error PrintL(4) arg count=3 (wrong length 3)
--- FailT "PrintL(4) arg count=3"
---
-data PrintL (n :: Nat) s p
-
-instance (KnownNat n
-        , PrintC bs
-        , (b,bs) ~ InductListP n a
-        , InductListC n a
-        , PrintfArg b
-        , PP s x ~ String
-        , PP p x ~ [a]
-        , P s x
-        , P p x
-        ) => P (PrintL n s p) x where
-  type PP (PrintL n s p) x = String
-  eval _ opts x = do
-    let msg0 = "PrintL(" ++ show n ++ ")"
-        n = nat @n
-    lrx <- runPQ msg0 (Proxy @s) (Proxy @p) opts x []
-    case lrx of
-      Left e -> pure e
-      Right (s,p,ss,pp) -> do
-        let hhs = [hh ss, hh pp]
-        if length p /= n then pure $ mkNode opts (FailT (msg0 <> " arg count=" ++ show (length p))) ("wrong length " ++ show (length p)) hhs
-        else do
-          lr <- catchitNF @_ @E.SomeException (prtC @bs s (inductListC @n @a p))
-          pure $ case lr of
-            Left e -> mkNode opts (FailT (msg0 <> "(" <> e <> ")")) ("s=" <> s) hhs
-            Right ret -> mkNode opts (PresentT ret) (msg0 <> " [" <> litL opts ret <> "]" <> " | s=" <> litL opts s) hhs
-
-type family CheckT (tp :: Type) :: Bool where
-  CheckT () = GL.TypeError ('GL.Text "Printfn: inductive tuple cannot be empty")
-  CheckT o = 'True
-
-type family ApplyConstT (ta :: Type) (b :: Type) :: Type where
---type family ApplyConstT ta b where -- less restrictive so allows ('Just Int) Bool through!
-  ApplyConstT (t a) b = t b
-  ApplyConstT ta b = GL.TypeError (
-       'GL.Text "ApplyConstT: (t a) b but found something else"
-       ':$$: 'GL.Text "t a = "
-       ':<>: 'GL.ShowType ta
-       ':$$: 'GL.Text "b = "
-       ':<>: 'GL.ShowType b)
-
--- | similar to 'Control.Applicative.<$'
---
--- >>> pz @(Fst Id <$ Snd Id) ("abc",Just 20)
--- PresentT (Just "abc")
---
-data p <$ q
-infixl 4 <$
-
-instance (P p x
-        , P q x
-        , Show (PP p x)
-        , Functor t
-        , PP q x ~ t c
-        , ApplyConstT (PP q x) (PP p x) ~ t (PP p x)
-        ) => P (p <$ q) x where
-  type PP (p <$ q) x = ApplyConstT (PP q x) (PP p x)
-  eval _ opts x = do
-    let msg0 = "(<$)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = p <$ q
-        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts p) [hh pp, hh qq]
-
-data p <* q
-infixl 4 <*
-
--- | similar to 'Control.Applicative.<*'
---
--- >>> pz @(Fst Id <* Snd Id) (Just "abc",Just 20)
--- PresentT (Just "abc")
---
-type ArrowRT p q = q <* p
-data p *> q
-infixl 4 *>
-
-instance P (ArrowRT p q) x => P (p *> q) x where
-  type PP (p *> q) x = PP (ArrowRT p q) x
-  eval _ = eval (Proxy @(ArrowRT p q))
-
-instance (Show (t c)
-        , P p x
-        , P q x
-        , Show (t b)
-        , Applicative t
-        , t b ~ PP p x
-        , PP q x ~ t c
-        ) => P (p <* q) x where
-  type PP (p <* q) x = PP p x
-  eval _ opts x = do
-    let msg0 = "(<*)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = p <* q
-        in mkNode opts (PresentT d) (show01' opts msg0 p "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
--- | similar to 'Control.Applicative.<|>'
---
--- >>> pz @(Fst Id <|> Snd Id) (Nothing,Just 20)
--- PresentT (Just 20)
---
--- >>> pz @(Fst Id <|> Snd Id) (Just 10,Just 20)
--- PresentT (Just 10)
---
--- >>> pz @(Fst Id <|> Snd Id) (Nothing,Nothing)
--- PresentT Nothing
---
-data p <|> q
-infixl 3 <|>
-
-instance (P p x
-        , P q x
-        , Show (t b)
-        , Alternative t
-        , t b ~ PP p x
-        , PP q x ~ t b
-        ) => P (p <|> q) x where
-  type PP (p <|> q) x = PP p x
-  eval _ opts x = do
-    let msg0 = "(<|>)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq) ->
-        let d = p <|> q
-        in mkNode opts (PresentT d) (show01' opts msg0 d "p=" p <> showVerbose opts " | q=" q) [hh pp, hh qq]
-
-
--- | similar to 'Control.Comonad.extract'
---
--- >>> pz @Extract (Nothing,Just 20)
--- PresentT (Just 20)
---
--- >>> pz @Extract (Identity 20)
--- PresentT 20
---
-data Extract
-instance (Show (t a)
-        , Show a
-        , Comonad t
-        ) => P Extract (t a) where
-  type PP Extract (t a) = a
-  eval _ opts ta =
-    let msg0 = "Extract"
-        d = extract ta
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d ta) []
-
--- | similar to 'Control.Comonad.duplicate'
---
--- >>> pz @Duplicate (20,"abc")
--- PresentT (20,(20,"abc"))
---
-data Duplicate
-
-instance (Show (t a)
-        , Show (t (t a))
-        , Comonad t
-        ) => P Duplicate (t a) where
-  type PP Duplicate (t a) = t (t a)
-  eval _ opts ta =
-    let msg0 = "Duplicate"
-        d = duplicate ta
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d ta) []
-
--- | similar to 'Control.Monad.join'
---
--- >>> pz @Join  (Just (Just 20))
--- PresentT (Just 20)
---
--- >>> pz @Join  ["ab","cd","","ef"]
--- PresentT "abcdef"
---
-data Join
-
-instance (Show (t (t a))
-        , Show (t a)
-        , Monad t
-        ) => P Join (t (t a)) where
-  type PP Join (t (t a)) = t a
-  eval _ opts tta =
-    let msg0 = "Join"
-        d = join tta
-    in pure $ mkNode opts (PresentT d) (show01 opts msg0 d tta) []
-
--- | function application for expressions: similar to 'GHC.Base.$'
---
--- pz @(Fst Id $$ Snd Id) ((*16),4)
--- PresentT 64
---
--- pz @(Id $$ "def") ("abc"<>)
--- PresentT "abcdef"
---
-data p $$ q
-infixl 0 $$
-
-instance (P p x
-        , P q x
-        , PP p x ~ (a -> b)
-        , FnT (PP p x) ~ b
-        , PP q x ~ a
-        , Show a
-        , Show b
-        ) => P (p $$ q) x where
-  type PP (p $$ q) x = FnT (PP p x)
-  eval _ opts x = do
-    let msg0 = "($$)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq)  ->
-        let d = p q
-        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
-
--- reify this so we can combine (type synonyms dont work as well)
-
--- | flipped function application for expressions: similar to 'Control.Lens.&'
---
--- pz @(Snd Id $& Fst Id) ((*16),4)
--- PresentT 64
---
--- pz @("def" $& Id) ("abc"<>)
--- PresentT "abcdef"
---
-data q $& p -- flips the args eg a & b & (,) = (b,a)
-infixr 1 $&
-
-instance (P p x
-        , P q x
-        , PP p x ~ (a -> b)
-        , FnT (PP p x) ~ b
-        , PP q x ~ a
-        , Show a
-        , Show b
-        ) => P (q $& p) x where
-  type PP (q $& p) x = FnT (PP p x)
-  eval _ opts x = do
-    let msg0 = "($&)"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,q,pp,qq)  ->
-        let d = p q
-        in mkNode opts (PresentT d) (msg0 <> " " <> showL opts q <> " = " <> showL opts d) [hh pp, hh qq]
-
-type family FnT ab :: Type where
-  FnT (a -> b) = b
-  FnT ab = GL.TypeError (
-      'GL.Text "FnT: expected Type -> Type but found a simple Type?"
-      ':$$: 'GL.Text "ab = "
-      ':<>: 'GL.ShowType ab)
-
--- | similar to 'T.strip' 'T.stripStart' 'T.stripEnd'
---
--- >>> pz @(TrimBoth (Snd Id)) (20," abc   " :: String)
--- PresentT "abc"
---
--- >>> pz @(TrimBoth (Snd Id)) (20,T.pack " abc   ")
--- PresentT "abc"
---
--- >>> pz @(TrimL (Snd Id)) (20," abc   ")
--- PresentT "abc   "
---
--- >>> pz @(TrimR (Snd Id)) (20," abc   ")
--- PresentT " abc"
---
--- >>> pz @(TrimR "  abc ") ()
--- PresentT "  abc"
---
--- >>> pz @(TrimR "") ()
--- PresentT ""
---
--- >>> pz @(TrimBoth "         ") ()
--- PresentT ""
---
--- >>> pz @(TrimBoth "") ()
--- PresentT ""
---
-data TrimImpl (left :: Bool) (right :: Bool) p
-
-instance (FailUnlessT (OrT l r)
-           ('GL.Text "TrimImpl: left and right cannot both be False")
-        , GetBool l
-        , GetBool r
-        , DTL.IsText (PP p x)
-        , P p x
-        ) => P (TrimImpl l r p) x where
-  type PP (TrimImpl l r p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Trim" ++ (if l && r then "Both" else if l then "L" else "R")
-        l = getBool @l
-        r = getBool @r
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right (view DTL.unpacked -> p) ->
-        let fl = if l then dropWhile isSpace else id
-            fr = if r then dropWhileEnd isSpace else id
-            b =  (fl . fr) p
-        in mkNode opts (PresentT (b ^. DTL.packed)) (msg0 <> litL opts b <> litVerbose opts " | " p) [hh pp]
-
-data TrimL p
-type TrimLT p = TrimImpl 'True 'False p
-
-instance P (TrimLT p) x => P (TrimL p) x where
-  type PP (TrimL p) x = PP (TrimLT p) x
-  eval _ = eval (Proxy @(TrimLT p))
-
-data TrimR p
-type TrimRT p = TrimImpl 'False 'True p
-
-instance P (TrimRT p) x => P (TrimR p) x where
-  type PP (TrimR p) x = PP (TrimRT p) x
-  eval _ = eval (Proxy @(TrimRT p))
-
-data TrimBoth p
-type TrimBothT p = TrimImpl 'True 'True p
-
-instance P (TrimBothT p) x => P (TrimBoth p) x where
-  type PP (TrimBoth p) x = PP (TrimBothT p) x
-  eval _ = eval (Proxy @(TrimBothT p))
-
--- | similar to 'T.stripLeft' 'T.stripRight'
---
--- >>> pz @(StripL "xyz" Id) ("xyzHello" :: String)
--- PresentT (Just "Hello")
---
--- >>> pz @(StripL "xyz" Id) (T.pack "xyzHello")
--- PresentT (Just "Hello")
---
--- >>> pz @(StripL "xyz" Id) "xywHello"
--- PresentT Nothing
---
--- >>> pz @(StripR "xyz" Id) "Hello xyz"
--- PresentT (Just "Hello ")
---
--- >>> pz @(StripR "xyz" Id) "xyzHelloxyw"
--- PresentT Nothing
---
--- >>> pz @(StripR "xyz" Id) ""
--- PresentT Nothing
---
--- >>> pz @(StripR "xyz" "xyz") ()
--- PresentT (Just "")
---
-data StripImpl(left :: Bool) p q
-
-instance (GetBool l
-        , PP p x ~ String
-        , P p x
-        , DTL.IsText (PP q x)
-        , P q x
-        ) => P (StripImpl l p q) x where
-  type PP (StripImpl l p q) x = Maybe (PP q x)
-  eval _ opts x = do
-    let msg0 = "Strip" ++ if l then "L" else "R"
-        l = getBool @l
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    pure $ case lr of
-      Left e -> e
-      Right (p,view DTL.unpacked -> q,pp,qq) ->
-        let b = if l then
-                  let (before,after) = splitAt (length p) q
-                  in if before == p then Just after else Nothing
-                else
-                  let (before,after) = splitAt (length q - length p) q
-                  in if after == p then Just before else Nothing
-        in mkNode opts (PresentT (fmap (view DTL.packed) b)) (msg0 <> showL opts b <> litVerbose opts " | p=" p <> litVerbose opts " | q=" q) [hh pp, hh qq]
-
-data StripL p q
-type StripLT p q = StripImpl 'True p q
-
-instance P (StripLT p q) x => P (StripL p q) x where
-  type PP (StripL p q) x = PP (StripLT p q) x
-  eval _ = eval (Proxy @(StripLT p q))
-
-data StripR p q
-type StripRT p q = StripImpl 'False p q
-
-instance P (StripRT p q) x => P (StripR p q) x where
-  type PP (StripR p q) x = PP (StripRT p q) x
-  eval _ = eval (Proxy @(StripRT p q))
-
--- | creates a promoted list of predicates and then evaluates them into a list. see PP instance for '[k]
---
--- >>> pz @(Repeat 4 (Succ Id)) 'c'
--- PresentT "dddd"
---
--- >>> pz @(Repeat 4 "abc") ()
--- PresentT ["abc","abc","abc","abc"]
---
-data Repeat (n :: Nat) p
-instance P (RepeatT n p) a => P (Repeat n p) a where
-  type PP (Repeat n p) a = PP (RepeatT n p) a
-  eval _ = eval (Proxy @(RepeatT n p))
-
--- | leverages 'Do' for repeating predicates (passthrough method)
--- same as @DoN n p == FoldN n p Id@ but more efficient
---
--- >>> pz @(DoN 4 (Succ Id)) 'c'
--- PresentT 'g'
---
--- >>> pz @(DoN 4 (Id <> " | ")) "abc"
--- PresentT "abc |  |  |  | "
---
--- >>> pz @(DoN 4 (Id <> "|" <> Id)) "abc"
--- PresentT "abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc|abc"
---
-data DoN (n :: Nat) p
-type DoNT (n :: Nat) p = Do (RepeatT n p)
-instance P (DoNT n p) a => P (DoN n p) a where
-  type PP (DoN n p) a = PP (DoNT n p) a
-  eval _ = eval (Proxy @(DoNT n p))
-
--- | extract the value from a 'Maybe' otherwise use the default value
---
--- >>> pz @(JustDef (1 % 4) Id) (Just 20.4)
--- PresentT (102 % 5)
---
--- >>> pz @(JustDef (1 % 4) Id) Nothing
--- PresentT (1 % 4)
---
--- >>> pz @(JustDef (MEmptyT _) Id) (Just "xy")
--- PresentT "xy"
---
--- >>> pz @(JustDef (MEmptyT _) Id) Nothing
--- PresentT ()
---
--- >>> pz @(JustDef (MEmptyT (SG.Sum _)) Id) Nothing
--- PresentT (Sum {getSum = 0})
---
-data JustDef p q
-
-instance ( PP p x ~ a
-         , PP q x ~ Maybe a
-         , P p x
-         , P q x)
-    => P (JustDef p q) x where
-  type PP (JustDef p q) x = MaybeT (PP q x)
-  eval _ opts x = do
-    let msg0 = "JustDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Just b -> pure $ mkNode opts (PresentT b) (msg0 <> " Just") [hh qq]
-          Nothing -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right b -> mkNode opts (PresentT b) (msg0 <> " Nothing") [hh qq, hh pp]
-
-
-type family MaybeT mb where
-  MaybeT (Maybe a) = a
-  MaybeT o = GL.TypeError (
-      'GL.Text "MaybeT: expected 'Maybe a' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
--- | extract the value from a 'Maybe' or fail
---
--- >>> pz @(JustFail "nope" Id) (Just 99)
--- PresentT 99
---
--- >>> pz @(JustFail "nope" Id) Nothing
--- FailT "nope"
---
--- >>> pz @(JustFail (PrintF "oops=%d" (Snd Id)) (Fst Id)) (Nothing, 123)
--- FailT "oops=123"
---
--- >>> pz @(JustFail (PrintF "oops=%d" (Snd Id)) (Fst Id)) (Just 'x', 123)
--- PresentT 'x'
---
-data JustFail p q
-
-instance ( PP p x ~ String
-         , PP q x ~ Maybe a
-         , P p x
-         , P q x)
-    => P (JustFail p q) x where
-  type PP (JustFail p q) x = MaybeT (PP q x)
-  eval _ opts x = do
-    let msg0 = "JustFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Just b -> pure $ mkNode opts (PresentT b) (msg0 <> " Just") [hh qq]
-          Nothing -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " Nothing") [hh qq, hh pp]
-
--- | extract the Left value from an 'Either' otherwise use the default value
---
--- if there is no Left value then \p\ is passed the Right value and the whole context
---
--- >>> pz @(LeftDef (1 % 4) Id) (Left 20.4)
--- PresentT (102 % 5)
---
--- >>> pz @(LeftDef (1 % 4) Id) (Right "aa")
--- PresentT (1 % 4)
---
--- >>> pz @(LeftDef (PrintT "found right=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Right "xy")
--- PresentT "found right=xy fst=123"
---
--- >>> pz @(LeftDef (MEmptyT _) Id) (Right 222)
--- PresentT ()
---
--- >>> pz @(LeftDef (MEmptyT (SG.Sum _)) Id) (Right 222)
--- PresentT (Sum {getSum = 0})
---
-data LeftDef p q
-
-instance ( PP q x ~ Either a b
-         , PP p (b,x) ~ a
-         , P q x
-         , P p (b,x)
-    ) => P (LeftDef p q) x where
-  type PP (LeftDef p q) x = LeftT (PP q x)
-  eval _ opts x = do
-    let msg0 = "LeftDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Left a -> pure $ mkNode opts (PresentT a) (msg0 <> " Left") [hh qq]
-          Right b -> do
-            pp <- eval (Proxy @p) opts (b,x)
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (PresentT p) (msg0 <> " Right") [hh qq, hh pp]
-
-type family LeftT lr where
-  LeftT (Either a b) = a
-  LeftT o = GL.TypeError (
-      'GL.Text "LeftT: expected 'Either a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
-type family RightT lr where
-  RightT (Either a b) = b
-  RightT o = GL.TypeError (
-      'GL.Text "RightT: expected 'Either a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
--- | extract the Right value from an 'Either'
---
--- if there is no Right value then \p\ is passed the Left value and the whole context
---
--- >>> pz @(RightDef (1 % 4) Id) (Right 20.4)
--- PresentT (102 % 5)
---
--- >>> pz @(RightDef (1 % 4) Id) (Left "aa")
--- PresentT (1 % 4)
---
--- >>> pz @(RightDef (PrintT "found left=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Left "xy")
--- PresentT "found left=xy fst=123"
---
--- >>> pz @(RightDef (MEmptyT _) Id) (Left 222)
--- PresentT ()
---
--- >>> pz @(RightDef (MEmptyT (SG.Sum _)) Id) (Left 222)
--- PresentT (Sum {getSum = 0})
---
-data RightDef p q
-
-instance ( PP q x ~ Either a b
-         , PP p (a,x) ~ b
-         , P q x
-         , P p (a,x)
-    ) => P (RightDef p q) x where
-  type PP (RightDef p q) x = RightT (PP q x)
-  eval _ opts x = do
-    let msg0 = "RightDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Right b -> pure $ mkNode opts (PresentT b) (msg0 <> " Right") [hh qq]
-          Left a -> do
-            pp <- eval (Proxy @p) opts (a,x)
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (PresentT p) (msg0 <> " Left") [hh qq, hh pp]
-
-
--- | extract the Left value from an 'Either' otherwise fail with a message
---
--- if there is no Left value then \p\ is passed the Right value and the whole context
---
--- >>> pz @(LeftFail "oops" Id) (Left 20.4)
--- PresentT 20.4
---
--- >>> pz @(LeftFail "oops" Id) (Right "aa")
--- FailT "oops"
---
--- >>> pz @(LeftFail (PrintT "found right=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Right "xy")
--- FailT "found right=xy fst=123"
---
--- >>> pz @(LeftFail (MEmptyT _) Id) (Right 222)
--- FailT ""
---
-data LeftFail p q
-
-instance ( PP p (b,x) ~ String
-         , PP q x ~ Either a b
-         , P p (b,x)
-         , P q x)
-    => P (LeftFail p q) x where
-  type PP (LeftFail p q) x = LeftT (PP q x)
-  eval _ opts x = do
-    let msg0 = "LeftFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Left a -> pure $ mkNode opts (PresentT a) (msg0 <> " Left") [hh qq]
-          Right b -> do
-            pp <- eval (Proxy @p) opts (b,x)
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " Right") [hh qq, hh pp]
-
-
--- | extract the Right value from an 'Either' otherwise fail with a message
---
--- if there is no Right value then \p\ is passed the Left value and the whole context
---
--- >>> pz @(RightFail "oops" Id) (Right 20.4)
--- PresentT 20.4
---
--- >>> pz @(RightFail "oops" Id) (Left "aa")
--- FailT "oops"
---
--- >>> pz @(RightFail (PrintT "found left=%s fst=%d" '(Fst Id,Fst (Snd Id))) (Snd Id)) (123,Left "xy")
--- FailT "found left=xy fst=123"
---
--- >>> pz @(RightFail (MEmptyT _) Id) (Left 222)
--- FailT ""
---
-data RightFail p q
-
-instance ( PP p (a,x) ~ String
-         , PP q x ~ Either a b
-         , P p (a,x)
-         , P q x)
-    => P (RightFail p q) x where
-  type PP (RightFail p q) x = RightT (PP q x)
-  eval _ opts x = do
-    let msg0 = "RightFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          Right b -> pure $ mkNode opts (PresentT b) (msg0 <> " Right") [hh qq]
-          Left a -> do
-            pp <- eval (Proxy @p) opts (a,x)
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " Left") [hh qq, hh pp]
-
-
-
--- | extract the This value from an 'These' otherwise use the default value
---
--- if there is no This value then \p\ is passed the whole context only
---
--- >>> pz @(ThisDef (1 % 4) Id) (This 20.4)
--- PresentT (102 % 5)
---
--- >>> pz @(ThisDef (1 % 4) Id) (That "aa")
--- PresentT (1 % 4)
---
--- >>> pz @(ThisDef (1 % 4) Id) (These 2.3 "aa")
--- PresentT (1 % 4)
---
--- >>> pz @(ThisDef (PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id)) (Snd Id)) (123,That "xy")
--- PresentT "found That \"xy\" fst=123"
---
--- >>> pz @(ThisDef (MEmptyT _) Id) (That 222)
--- PresentT ()
---
--- >>> pz @(ThisDef (MEmptyT (SG.Sum _)) Id) (These 222 'x')
--- PresentT (Sum {getSum = 0})
---
-data ThisDef p q
-
-instance ( PP q x ~ These a b
-         , PP p x ~ a
-         , P q x
-         , P p x
-    ) => P (ThisDef p q) x where
-  type PP (ThisDef p q) x = ThisT (PP q x)
-  eval _ opts x = do
-    let msg0 = "ThisDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          This a -> pure $ mkNode opts (PresentT a) (msg0 <> " This") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
-type family ThisT lr where
-  ThisT (These a b) = a
-  ThisT o = GL.TypeError (
-      'GL.Text "ThisT: expected 'These a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
-type family ThatT lr where
-  ThatT (These a b) = b
-  ThatT o = GL.TypeError (
-      'GL.Text "ThatT: expected 'These a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
-type family TheseT lr where
-  TheseT (These a b) = (a,b)
-  TheseT o = GL.TypeError (
-      'GL.Text "TheseT: expected 'These a b' "
-      ':$$: 'GL.Text "o = "
-      ':<>: 'GL.ShowType o)
-
-
--- | extract the That value from an 'These' otherwise use the default value
---
--- if there is no That value then \p\ is passed the whole context only
---
--- >>> pz @(ThatDef (1 % 4) Id) (That 20.4)
--- PresentT (102 % 5)
---
--- >>> pz @(ThatDef (1 % 4) Id) (This "aa")
--- PresentT (1 % 4)
---
--- >>> pz @(ThatDef (1 % 4) Id) (These "aa" 2.3)
--- PresentT (1 % 4)
---
--- >>> pz @(ThatDef (PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id)) (Snd Id)) (123,This "xy")
--- PresentT "found This \"xy\" fst=123"
---
--- >>> pz @(ThatDef (MEmptyT _) Id) (This 222)
--- PresentT ()
---
--- >>> pz @(ThatDef (MEmptyT (SG.Sum _)) Id) (These 'x' 1120)
--- PresentT (Sum {getSum = 0})
---
-data ThatDef p q
-
-instance ( PP q x ~ These a b
-         , PP p x ~ b
-         , P q x
-         , P p x
-    ) => P (ThatDef p q) x where
-  type PP (ThatDef p q) x = ThatT (PP q x)
-  eval _ opts x = do
-    let msg0 = "ThatDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          That a -> pure $ mkNode opts (PresentT a) (msg0 <> " That") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
--- | extract the These value from an 'These' otherwise use the default value
---
--- if there is no These value then \p\ is passed the whole context only
---
--- >>> pz @(TheseDef '(1 % 4,"zz") Id) (These 20.4 "x")
--- PresentT (102 % 5,"x")
---
--- >>> pz @(TheseDef '(1 % 4,"zz") Id) (This 20.4)
--- PresentT (1 % 4,"zz")
---
--- >>> pz @(TheseDef '(1 % 4,"zz") Id) (That "x")
--- PresentT (1 % 4,"zz")
---
--- >>> pz @(TheseDef '(PrintT "found %s fst=%d" '(ShowP (Snd Id), Fst Id),999) (Snd Id)) (123,This "xy")
--- PresentT ("found This \"xy\" fst=123",999)
---
--- >>> pz @(TheseDef (MEmptyT (SG.Sum _, String)) Id) (This 222)
--- PresentT (Sum {getSum = 0},"")
---
--- >>> pz @(TheseDef (MEmptyT _) Id) (These (222 :: SG.Sum Int) "aa")
--- PresentT (Sum {getSum = 222},"aa")
---
-data TheseDef p q
-
-instance ( PP q x ~ These a b
-         , PP p x ~ (a,b)
-         , P q x
-         , P p x
-    ) => P (TheseDef p q) x where
-  type PP (TheseDef p q) x = TheseT (PP q x)
-  eval _ opts x = do
-    let msg0 = "TheseDef"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          These a b -> pure $ mkNode opts (PresentT (a,b)) (msg0 <> " These") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (PresentT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
-
--- | extract the This value from a 'These' otherwise fail with a message
---
--- if there is no This value then \p\ is passed the whole context only
---
--- >>> pz @(ThisFail "oops" Id) (This 20.4)
--- PresentT 20.4
---
--- >>> pz @(ThisFail "oops" Id) (That "aa")
--- FailT "oops"
---
--- >>> pz @(ThisFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,That "xy")
--- FailT "found That \"xy\" fst=123"
---
--- >>> pz @(ThisFail (MEmptyT _) Id) (That 222)
--- FailT ""
---
-data ThisFail p q
-
-instance ( PP p x ~ String
-         , PP q x ~ These a b
-         , P p x
-         , P q x)
-    => P (ThisFail p q) x where
-  type PP (ThisFail p q) x = ThisT (PP q x)
-  eval _ opts x = do
-    let msg0 = "ThisFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          This a -> pure $ mkNode opts (PresentT a) (msg0 <> " This") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
-
--- | extract the That value from a 'These' otherwise fail with a message
---
--- if there is no That value then \p\ is passed the whole context only
---
--- >>> pz @(ThatFail "oops" Id) (That 20.4)
--- PresentT 20.4
---
--- >>> pz @(ThatFail "oops" Id) (This "aa")
--- FailT "oops"
---
--- >>> pz @(ThatFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,This "xy")
--- FailT "found This \"xy\" fst=123"
---
--- >>> pz @(ThatFail (MEmptyT _) Id) (This 222)
--- FailT ""
---
-data ThatFail p q
-
-instance ( PP p x ~ String
-         , PP q x ~ These a b
-         , P p x
-         , P q x)
-    => P (ThatFail p q) x where
-  type PP (ThatFail p q) x = ThatT (PP q x)
-  eval _ opts x = do
-    let msg0 = "ThatFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          That a -> pure $ mkNode opts (PresentT a) (msg0 <> " That") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
-
-
-
--- | extract the These value from a 'These' otherwise fail with a message
---
--- if there is no These value then \p\ is passed the whole context only
---
--- >>> pz @(TheseFail "oops" Id) (These "abc" 20.4)
--- PresentT ("abc",20.4)
---
--- >>> pz @(TheseFail "oops" Id) (That "aa")
--- FailT "oops"
---
--- >>> pz @(TheseFail (PrintT "found %s fst=%d" '(ShowP (Snd Id),Fst Id)) (Snd Id)) (123,That "xy")
--- FailT "found That \"xy\" fst=123"
---
--- >>> pz @(TheseFail (MEmptyT _) Id) (That 222)
--- FailT ""
---
-data TheseFail p q
-
-instance ( PP p x ~ String
-         , PP q x ~ These a b
-         , P p x
-         , P q x)
-    => P (TheseFail p q) x where
-  type PP (TheseFail p q) x = TheseT (PP q x)
-  eval _ opts x = do
-    let msg0 = "TheseFail"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q ->
-        case q of
-          These a b -> pure $ mkNode opts (PresentT (a,b)) (msg0 <> " These") [hh qq]
-          _ -> do
-            pp <- eval (Proxy @p) opts x
-            pure $ case getValueLR opts msg0 pp [hh qq] of
-              Left e -> e
-              Right p -> mkNode opts (FailT p) (msg0 <> " " <> showThese q) [hh qq, hh pp]
-
--- | takes the head of a list like container
---
--- >>> pz @(Head Id) "abcd"
--- PresentT 'a'
---
--- >>> pz @(Head Id) []
--- FailT "Head(empty)"
---
-data Head p
-
-instance (Show (ConsT s)
-        , Show s
-        , Cons s s (ConsT s) (ConsT s)
-        , PP p x ~ s
-        , P p x
-        ) => P (Head p) x where
-  type PP (Head p) x = ConsT (PP p x)
-  eval _ opts x = do
-    let msg0 = "Head"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case p ^? _Cons of
-          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
-          Just (a,_) -> mkNode opts (PresentT a) (show01 opts msg0 a p) [hh pp]
-
--- | takes the tail of a list like container
---
--- >>> pz @(Tail Id) "abcd"
--- PresentT "bcd"
---
--- >>> pz @(Tail Id) []
--- FailT "Tail(empty)"
---
-data Tail p
-
-instance (Show s
-        , Cons s s (ConsT s) (ConsT s)
-        , PP p x ~ s
-        , P p x
-        ) => P (Tail p) x where
-  type PP (Tail p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Tail"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case p ^? _Cons of
-          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
-          Just (_,as) -> mkNode opts (PresentT as) (show01 opts msg0 as p) [hh pp]
-
-
--- | takes the last of a list like container
---
--- >>> pz @(Last Id) "abcd"
--- PresentT 'd'
---
--- >>> pz @(Last Id) []
--- FailT "Last(empty)"
---
-
-data Last p
-
-instance (Show (ConsT s)
-        , Show s
-        , Snoc s s (ConsT s) (ConsT s)
-        , PP p x ~ s
-        , P p x
-        ) => P (Last p) x where
-  type PP (Last p) x = ConsT (PP p x)
-  eval _ opts x = do
-    let msg0 = "Last"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case p ^? _Snoc of
-          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
-          Just (_,a) -> mkNode opts (PresentT a) (show01 opts msg0 a p) [hh pp]
-
--- | takes the init of a list like container
---
--- >>> pz @(Init Id) "abcd"
--- PresentT "abc"
---
--- >>> pz @(Init Id) (T.pack "abcd")
--- PresentT "abc"
---
--- >>> pz @(Init Id) []
--- FailT "Init(empty)"
---
-
-data Init p
-
-instance (Show s
-        , Snoc s s (ConsT s) (ConsT s)
-        , PP p x ~ s
-        , P p x
-        ) => P (Init p) x where
-  type PP (Init p) x = PP p x
-  eval _ opts x = do
-    let msg0 = "Init"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case p ^? _Snoc of
-          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "" [hh pp]
-          Just (as,_) -> mkNode opts (PresentT as) (show01 opts msg0 as p) [hh pp]
-
-
--- | tries to extract @a@ from @Maybe a@ otherwise it fails
---
--- >>> pz @(Just Id) (Just "abc")
--- PresentT "abc"
---
--- >>> pz @(Just Id) Nothing
--- FailT "Just(empty)"
---
-data Just p
-
-instance (Show a
-        , PP p x ~ Maybe a
-        , P p x
-        ) => P (Just p) x where
-  type PP (Just p) x = MaybeT (PP p x)
-  eval _ opts x = do
-    let msg0 = "Just"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        case p of
-          Nothing -> mkNode opts (FailT (msg0 <> "(empty)")) "found Nothing" [hh pp]
-          Just d -> mkNode opts (PresentT d) (show01 opts msg0 d p) [hh pp]
-
-
--- | compose simple functions
---
--- >>> pl @(Dot '[Thd,Snd,Fst] Id) ((1,(2,9,10)),(3,4))
--- Present 10 (Thd 10 | (2,9,10))
--- PresentT 10
---
-data Dot (ps :: [Type -> Type]) (q :: Type)
-instance (P (DotExpandT ps q) a) => P (Dot ps q) a where
-  type PP (Dot ps q) a = PP (DotExpandT ps q) a
-  eval _ = eval (Proxy @(DotExpandT ps q))
-
-type family DotExpandT (ps :: [Type -> Type]) (q :: Type) :: Type where
-  DotExpandT '[] _ = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
-  DotExpandT '[p] q = p $ q
-  DotExpandT (p ': p1 ': ps) q = p $ DotExpandT (p1 ': ps) q
-
--- | reversed dot
---
--- >>> pl @(RDot '[Fst,Snd,Thd] Id) ((1,(2,9,10)),(3,4))
--- Present 10 (Thd 10 | (2,9,10))
--- PresentT 10
---
--- >>> pl @(RDot '[Fst,Snd] Id) (('a',2),(True,"zy"))
--- Present 2 (Snd 2 | ('a',2))
--- PresentT 2
---
-data RDot (ps :: [Type -> Type]) (q :: Type)
-instance P (RDotExpandT ps q) a => P (RDot ps q) a where
-  type PP (RDot ps q) a = PP (RDotExpandT ps q) a
-  eval _ = eval (Proxy @(RDotExpandT ps q))
-
-type family RDotExpandT (ps :: [Type -> Type]) (q :: Type) :: Type where
-  RDotExpandT '[] _ = GL.TypeError ('GL.Text "'[] invalid: requires at least one predicate in the list")
-  RDotExpandT '[p] q = p $ q
-  RDotExpandT (p ': p1 ': ps) q = RDotExpandT (p1 ': ps) (p $ q)
-
--- | like 'GHC.Base.$' for expressions
---
--- >>> pl @(Fst $ Snd $ Id) ((1,2),(3,4))
--- Present 3 (Fst 3 | (3,4))
--- PresentT 3
---
--- >>> pl @((<=) 4 $ Fst $ Snd $ Id) ((1,2),(3,4))
--- False (4 <= 3)
--- FalseT
---
-data (p :: k -> k1) $ (q :: k)
-infixr 0 $
-
-instance P (p q) a => P (p $ q) a where
-  type PP (p $ q) a = PP (p q) a
-  eval _  = eval (Proxy @(p q))
-
--- | similar to 'Control.Lens.&'
---
--- >>> pl @(Id & Fst & Singleton & Length) (13,"xyzw")
--- Present 1 (Length 1 | [13])
--- PresentT 1
---
--- >>> pl @(2 & (&&&) "abc") ()
--- Present ("abc",2) (W '(,))
--- PresentT ("abc",2)
---
--- >>> pl @(2 & '(,) "abc") ()
--- Present ("abc",2) ('(,))
--- PresentT ("abc",2)
---
--- >>> pl @('(,) 4 $ '(,) 7 $ "aa") ()
--- Present (4,(7,"aa")) ('(,))
--- PresentT (4,(7,"aa"))
---
--- >>> pl @(Thd $ Snd $ Fst Id) ((1,("W",9,'a')),(3,4))
--- Present 'a' (Thd 'a' | ("W",9,'a'))
--- PresentT 'a'
---
-data (q :: k) & (p :: k -> k1)
-infixl 1 &
-
-instance P (p q) a => P (q & p) a where
-  type PP (q & p) a = PP (p q) a
-  eval _ = eval (Proxy @(p q))
-
--- | creates a constant expression ignoring the second argument
---
--- >>> pl @(RDot '[Fst,Snd,Thd,K "xxx"] Id) ((1,(2,9,10)),(3,4))
--- Present "xxx" (K '"xxx")
--- PresentT "xxx"
---
--- >>> pl @(RDot '[Fst,Snd,Thd,K '("abc",Id)] Id) ((1,(2,9,10)),(3,4))
--- Present ("abc",((1,(2,9,10)),(3,4))) (K '(,))
--- PresentT ("abc",((1,(2,9,10)),(3,4)))
---
--- >>> pl @(Thd $ Snd $ Fst $ K Id "dud") ((1,("W",9,'a')),(3,4))
--- Present 'a' (Thd 'a' | ("W",9,'a'))
--- PresentT 'a'
---
--- >>> pl @((Thd $ Snd $ Fst $ K Id "dud") >> Pred Id) ((1,("W",9,'a')),(3,4))
--- Present '`' ((>>) '`' | {Pred '`' | 'a'})
--- PresentT '`'
---
-data K (p :: k) (q :: k1)
-instance P p a => P (K p q) a where
-  type PP (K p q) a = PP p a
-  eval _ = eval (Proxy @(Msg "K " p))
-
--- | applies \'p\' to the first and second slot of an n-tuple
---
--- >>> pl @(Both Len (Fst Id)) (("abc",[10..17],1,2,3),True)
--- Present (3,8) (Both)
--- PresentT (3,8)
---
--- >>> pl @(Both (Pred Id) $ Fst Id) ((12,'z',[10..17]),True)
--- Present (11,'y') (Both)
--- PresentT (11,'y')
---
--- >>> pl @(Both (Succ Id) Id) (4,'a')
--- Present (5,'b') (Both)
--- PresentT (5,'b')
---
--- >>> pl @(Both Len (Fst Id)) (("abc",[10..17]),True)
--- Present (3,8) (Both)
--- PresentT (3,8)
---
--- >>> pl @(Both (ReadP Day Id) Id) ("1999-01-01","2001-02-12")
--- Present (1999-01-01,2001-02-12) (Both)
--- PresentT (1999-01-01,2001-02-12)
---
-data Both p q
-instance ( ExtractL1C (PP q x)
-         , ExtractL2C (PP q x)
-         , P p (ExtractL1T (PP q x))
-         , P p (ExtractL2T (PP q x))
-         , P q x
-   ) => P (Both p q) x where
-  type PP (Both p q) x = (PP p (ExtractL1T (PP q x)), PP p (ExtractL2T (PP q x)))
-  eval _ opts x = do
-    let msg0 = "Both"
-    qq <- eval (Proxy @q) opts x
-    case getValueLR opts msg0 qq [] of
-      Left e -> pure e
-      Right q -> do
-        let (a,a') = (extractL1C q, extractL2C q)
-        pp <- eval (Proxy @p) opts a
-        case getValueLR opts msg0 pp [hh qq] of
-          Left e -> pure e
-          Right b -> do
-            pp' <- eval (Proxy @p) opts a'
-            pure $ case getValueLR opts msg0 pp' [hh qq, hh pp] of
-              Left e -> e
-              Right b' ->
-                mkNode opts (PresentT (b,b')) msg0 [hh qq, hh pp, hh pp']
-
--- | gets the singleton value from a foldable
---
--- >>> pl @(OneP Id) [10..15]
--- Error OneP 6 elements (expected one element)
--- FailT "OneP 6 elements"
---
--- >>> pl @(OneP Id) [10]
--- Present 10 (OneP)
--- PresentT 10
---
--- >>> pl @(OneP Id) []
--- Error OneP empty (expected one element)
--- FailT "OneP empty"
---
--- >>> pl @(OneP Id) (Just 10)
--- Present 10 (OneP)
--- PresentT 10
---
--- >>> pl @(OneP Id) Nothing
--- Error OneP empty (expected one element)
--- FailT "OneP empty"
---
-data OneP p
-instance (Foldable t
-        , PP p x ~ t a
-        , P p x
-        ) => P (OneP p) x where
-  type PP (OneP p) x = ExtractAFromTA (PP p x)
-  eval _ opts x = do
-    let msg0 = "OneP"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p -> case toList p of
-                   [] -> mkNode opts (FailT (msg0 <> " empty")) "expected one element" [hh pp]
-                   [a] -> mkNode opts (PresentT a) msg0 [hh pp]
-                   as -> let n = length as
-                         in mkNode opts (FailT (msg0 <> " " <> show n <> " elements")) "expected one element" [hh pp]
-
--- | parse json data
---
--- >>> pl @(ParseJson (Int,String) Id) "[10,\"abc\"]"
--- Present (10,"abc") (ParseJson (Int,[Char]) (10,"abc"))
--- PresentT (10,"abc")
---
--- >>> pl @(ParseJson (Int,String) Id) "[10,\"abc\",99]"
--- Error ParseJson (Int,[Char])([10,"abc",...) Error in $ (Error in $: cannot unpack array of length 3 into a tuple of length 2 | [10,"abc",99])
--- FailT "ParseJson (Int,[Char])([10,\"abc\",...) Error in $"
---
--- >>> pl @(ParseJson (Int,Bool) (FromString _ Id)) ("[1,true]" :: String)
--- Present (1,True) (ParseJson (Int,Bool) (1,True))
--- PresentT (1,True)
---
--- >>> pl @(ParseJson (Int,Bool) Id) (A.encode (1,True))
--- Present (1,True) (ParseJson (Int,Bool) (1,True))
--- PresentT (1,True)
---
--- >>> pl @(ParseJson () Id) "[1,true]"
--- Error ParseJson ()([1,true]) Error in $ (Error in $: parsing () failed, expected an empty array | [1,true])
--- FailT "ParseJson ()([1,true]) Error in $"
---
-data ParseJson' t p
-
-instance (P p x
-        , PP p x ~ BL8.ByteString
-        , Typeable (PP t x)
-        , Show (PP t x)
-        , A.FromJSON (PP t x)
-        ) => P (ParseJson' t p) x where
-  type PP (ParseJson' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "ParseJson " <> t
-        t = showT @(PP t x)
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right s ->
-        let hhs = [hh pp]
-            msg1 = msg0 <> "(" ++ litBL opts { oWidth = oWidth opts `div` 3 } s ++ ")"
-        in case A.eitherDecode' s of
-           Right b -> mkNode opts (PresentT b) (msg0 <> " " ++ showL opts { oWidth = oWidth opts `div` 2 } b) hhs
-           Left e -> mkNode opts (FailT (msg1 <> " " <> takeWhile (/=':') e) ) (e <> " | " <> litBL opts s) hhs
-
-data ParseJson (t :: Type) p
-type ParseJsonT (t :: Type) p = ParseJson' (Hole t) p
-
-instance P (ParseJsonT t p) x => P (ParseJson t p) x where
-  type PP (ParseJson t p) x = PP (ParseJsonT t p) x
-  eval _ = eval (Proxy @(ParseJsonT t p))
-
--- | parse a json file
---
--- >>> pz @(ParseJsonFile [A.Value] "test1.json" >> Id !! 2) ()
--- PresentT (Object (fromList [("lastName",String "Doe"),("age",Number 45.0),("firstName",String "John"),("likesPizza",Bool False)]))
---
-data ParseJsonFile' t p
-
-instance (P p x
-        , PP p x ~ String
-        , Typeable (PP t x)
-        , Show (PP t x)
-        , A.FromJSON (PP t x)
-        ) => P (ParseJsonFile' t p) x where
-  type PP (ParseJsonFile' t p) x = PP t x
-  eval _ opts x = do
-    let msg0 = "ParseJsonFile " <> t
-        t = showT @(PP t x)
-    pp <- eval (Proxy @p) opts x
-    case getValueLR opts msg0 pp [] of
-      Left e -> pure e
-      Right p -> do
-        let hhs = [hh pp]
-            msg1 = msg0 <> "(" <> p <> ")"
-        mb <- runIO $ do
-                b <- doesFileExist p
-                if b then Just <$> BS8.readFile p
-                else pure Nothing
-        pure $ case mb of
-          Nothing -> mkNode opts (FailT msg1) "" hhs
-          Just Nothing -> mkNode opts (FailT (msg1 <> " file does not exist")) "" hhs
-          Just (Just s) ->
-            case A.eitherDecodeStrict' s of
-               Right b -> mkNode opts (PresentT b) (msg1 <> " " ++ showL opts b) hhs
-               Left e -> mkNode opts (FailT (msg1 <> " " <> takeWhile (/=':') e)) (e <> " | " <> litBS opts s) hhs
-
-data ParseJsonFile (t :: Type) p
-type ParseJsonFileT (t :: Type) p = ParseJsonFile' (Hole t) p
-
-instance P (ParseJsonFileT t p) x => P (ParseJsonFile t p) x where
-  type PP (ParseJsonFile t p) x = PP (ParseJsonFileT t p) x
-  eval _ = eval (Proxy @(ParseJsonFileT t p))
-
--- | encode json
---
--- >>> pl @(EncodeJson Id) (10,"def")
--- Present "[10,\"def\"]" (EncodeJson [10,"def"])
--- PresentT "[10,\"def\"]"
---
--- >>> pl @(EncodeJson Id >> ParseJson (Int,Bool) Id) (1,True)
--- Present (1,True) ((>>) (1,True) | {ParseJson (Int,Bool) (1,True)})
--- PresentT (1,True)
---
-data EncodeJson p
-
-instance ( A.ToJSON (PP p x)
-         , P p x
-         ) => P (EncodeJson p) x where
-  type PP (EncodeJson p) x = BL8.ByteString
-  eval _ opts x = do
-    let msg0 = "EncodeJson"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = A.encode p
-        in mkNode opts (PresentT d) (msg0 <> " " <> litL opts (litBL opts d)) [hh pp]
-
--- | encode a json file
-data EncodeJsonFile p q
-
-instance (PP p x ~ String
-        , P p x
-        , A.ToJSON (PP q x)
-        , P q x
-        ) => P (EncodeJsonFile p q) x where
-  type PP (EncodeJsonFile p q) x = ()
-  eval _ opts x = do
-    let msg0 = "EncodeJsonFile"
-    lr <- runPQ msg0 (Proxy @p) (Proxy @q) opts x []
-    case lr of
-      Left e -> pure e
-      Right (p,q,pp,qq) -> do
-        let d = A.encode q
-            hhs = [hh pp, hh qq]
-        mb <- runIO $ BL8.writeFile p d
-        pure $ case mb of
-          Nothing -> mkNode opts (FailT (msg0 <> " must run in IO")) "" hhs
-          Just () -> mkNode opts (PresentT ()) (msg0 <> " " <> litL opts (litBL opts d)) hhs
-
--- | uncurry experiment
---
--- >>> pl @(Uncurry Between (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2019-10-12"
--- False (Uncurry (2019-10-12 <= 2018-12-30))
--- FalseT
---
--- >>> pl @(Uncurry Between (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2017-10-12"
--- True (Uncurry (2017-04-11 <= 2017-10-12 <= 2018-12-30))
--- TrueT
---
--- >>> pl @(Uncurry Between (ReadP (Day,Day) "(2017-04-11,2018-12-30)") (ReadP Day Id)) "2016-10-12"
--- False (Uncurry (2017-04-11 <= 2016-10-12))
--- FalseT
---
-data Uncurry (p :: Type -> Type -> Type -> Type) q r
-
-instance (PP q x ~ (a,b)
-        , PP (p a b (PP r x)) x ~ PP (p (Fst Id) (Snd Id) (Thd Id)) (a, b, PP r x)
-        , P q x
-        , P r x
-        , P (p (Fst Id) (Snd Id) (Thd Id)) (a,b,PP r x)
-     ) => P (Uncurry p q r) x where
-  type PP (Uncurry p q r) x = PP (p (ExtractL1T (PP q x)) (ExtractL2T (PP q x)) (PP r x)) x
-  eval _ opts x = do
-    let msg0 = "Uncurry"
-    lr <- runPQ msg0 (Proxy @q) (Proxy @r) opts x []
-    case lr of
-      Left e -> pure e
-      Right ((q1,q2),r,qq,rr) -> do
-        let hhs0 = [hh qq, hh rr]
-        pp <- eval (Proxy @(p (Fst Id) (Snd Id) (Thd Id))) opts (q1,q2,r)
-        pure $ case getValueLR opts msg0 pp hhs0 of
-          Left e -> e
-          Right _ ->
-            let hhs = hhs0 ++ [hh pp]
-            in mkNode opts (_tBool pp) (msg0 <> litVerbose opts " " (topMessage pp)) hhs
-
--- | like 'Predicate.Prelude.&&' but for a tuple
---
--- >>> pl @(SplitAt 4 "abcdefg" >> Len > 4 &* Len < 5) ()
--- False ((>>) False | {False (&*) True | (4 > 4)})
--- FalseT
---
-data AndA p q r
-instance (PP r x ~ (a,b)
-        , PP p a ~ Bool
-        , PP q b ~ Bool
-        , P p a
-        , P q b
-        , P r x
-        ) => P (AndA p q r) x where
-  type PP (AndA p q r) x = Bool
-  eval _ opts x = do
-    let msg0 = "(&*)"
-    rr <- eval (Proxy @r) opts x
-    case getValueLR opts msg0 rr [] of
-      Left e -> pure e
-      Right (r1,r2) -> do
-        pp <- evalBool (Proxy @p) opts r1
-        case getValueLR opts msg0 pp [hh rr] of
-          Left e -> pure e
-          Right p -> do
-            qq <- evalBool (Proxy @q) opts r2
-            pure $ case getValueLR opts msg0 qq [hh rr, hh pp] of
-              Left e -> e
-              Right q ->
-                let zz = case (p,q) of
-                          (True, True) -> ""
-                          (False, True) -> topMessage pp
-                          (True, False) -> topMessage qq
-                          (False, False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-                in mkNodeB opts (p&&q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh rr, hh pp, hh qq]
-
-data p &* q
-type AndAT p q = AndA p q Id
-infixr 3 &*
-
-instance P (AndAT p q) x => P (p &* q) x where
-  type PP (p &* q) x = PP (AndAT p q) x
-  eval _ = evalBool (Proxy @(AndAT p q))
-
-{-
-data p &&! q
-type AndAT' p q = (Fst Id >> p) && (Snd Id >> q)
-infixr 3 &&!
-
-instance (P (AndAT' p q) x
-        ) => P (p &&! q) x where
-  type PP (p &&! q) x = PP (AndAT' p q) x
-  eval _ = evalBool (Proxy @(AndAT' p q))
--}
-
--- | like 'Predicate.Prelude.||' but for a tuple
---
--- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,8,14,44],9)
--- True (True (|+) False)
--- TrueT
---
--- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,14],9)
--- False (False (|+) False | (32 > 44) (|+) (9 < 2))
--- FalseT
---
--- >>> pl @(Sum > 44 |+ Id < 2) ([5,6,7,14],1)
--- True (False (|+) True)
--- TrueT
---
-data OrA p q r
-instance (PP r x ~ (a,b)
-        , PP p a ~ Bool
-        , PP q b ~ Bool
-        , P p a
-        , P q b
-        , P r x
-        ) => P (OrA p q r) x where
-  type PP (OrA p q r) x = Bool
-  eval _ opts x = do
-    let msg0 = "(|+)"
-    rr <- eval (Proxy @r) opts x
-    case getValueLR opts msg0 rr [] of
-      Left e -> pure e
-      Right (r1,r2) -> do
-        pp <- evalBool (Proxy @p) opts r1
-        case getValueLR opts msg0 pp [hh rr] of
-          Left e -> pure e
-          Right p -> do
-            qq <- evalBool (Proxy @q) opts r2
-            pure $ case getValueLR opts msg0 qq [hh rr, hh pp] of
-              Left e -> e
-              Right q ->
-                let zz = case (p,q) of
-                          (False,False) -> topMessage pp <> " " <> msg0 <> " " <> topMessage qq
-                          _ -> ""
-                in mkNodeB opts (p||q) (showL opts p <> " " <> msg0 <> " " <> showL opts q <> (if null zz then zz else " | " <> zz)) [hh rr, hh pp, hh qq]
-
-data p |+ q
-type OrAT p q = OrA p q Id
-infixr 3 |+
-
-instance P (OrAT p q) x => P (p |+ q) x where
-  type PP (p |+ q) x = PP (OrAT p q) x
-  eval _ = evalBool (Proxy @(OrAT p q))
-
--- | very simple conversion to a string
-data ToString p
-instance ( ToStringC (PP p x)
-         , P p x
-         ) => P (ToString p) x where
-  type PP (ToString p) x = String
-  eval _ opts x = do
-    let msg0 = "ToString"
-    pp <- eval (Proxy @p) opts x
-    pure $ case getValueLR opts msg0 pp [] of
-      Left e -> e
-      Right p ->
-        let d = toStringC p
-        in mkNode opts (PresentT d) msg0 [hh pp]
-
-class ToStringC a where
-  toStringC :: a -> String
-instance ToStringC String where
-  toStringC = id
-instance ToStringC T.Text where
-  toStringC = T.unpack
-instance ToStringC TL.Text where
-  toStringC = TL.unpack
-instance ToStringC BL8.ByteString where
-  toStringC = BL8.unpack
-instance ToStringC BS8.ByteString where
-  toStringC = BS8.unpack
-
--- | splits a list pointed to by \'p\' into lists of size \'n\'
---
--- >>> pz @(ChunksOf 2 Id) "abcdef"
--- PresentT ["ab","cd","ef"]
---
--- >>> pz @(ChunksOf 2 Id) "abcdefg"
--- PresentT ["ab","cd","ef","g"]
---
--- >>> pz @(ChunksOf 2 Id) ""
--- PresentT []
---
--- >>> pz @(ChunksOf 2 Id) "a"
--- PresentT ["a"]
---
-data ChunksOf n p
-
-instance (PP p a ~ [b]
-        , P n a
-        , P p a
-        , Show b
-        , Integral (PP n a)
-        ) => P (ChunksOf n p) a where
-  type PP (ChunksOf n p) a = [PP p a]
-  eval _ opts a = do
-    let msg0 = "ChunksOf"
-    lr <- runPQ msg0 (Proxy @n) (Proxy @p) opts a []
-    pure $ case lr of
-      Left e -> e
-      Right (fromIntegral -> n,p,pp,qq) ->
-        let hhs = [hh pp, hh qq]
-            msg1 = msg0 <> " " <> showL opts n <> " " <> showL opts p
-        in if n <= 0 then mkNode opts (FailT (msg0 <> " n<1")) "" hhs
-           else let ret = unfoldr (\s -> if null s then Nothing else Just $ splitAt n s) p
-                in mkNode opts (PresentT ret) (show01' opts msg1 ret "n=" n <> showVerbose opts " | " p) hhs
-
-data Rotate n p
-type RotateT n p = SplitAt n p >> Swap >> First Reverse >> SapA
-
-instance P (RotateT n p) x => P (Rotate n p) x where
-  type PP (Rotate n p) x = PP (RotateT n p) x
-  eval _ = eval (Proxy @(RotateT n p))
-
-type Tuple2 p = '(p !! 0, p !! 1)
-type Tuple3 p = '(p !! 0, p !! 1, p !! 2)
-type Tuple4 p = '(p !! 0, p !! 1, p !! 2, p !! 3)
-type Tuple5 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4)
-type Tuple6 p = '(p !! 0, p !! 1, p !! 2, p !! 3, p !! 4, p !! 5)
+{- |
+     Dsl for evaluating and displaying type level expressions
+-}
+module Predicate.Prelude (
+    module Predicate.Core
+  , module Predicate.Util
+  , module Predicate.Data.Char
+  , module Predicate.Data.Condition
+  , module Predicate.Data.DateTime
+  , module Predicate.Data.Either
+  , module Predicate.Data.Enum
+  , module Predicate.Data.Extra
+  , module Predicate.Data.Foldable
+  , module Predicate.Data.Index
+  , module Predicate.Data.Iterator
+  , module Predicate.Data.IO
+  , module Predicate.Data.Json
+  , module Predicate.Data.List
+  , module Predicate.Data.Maybe
+  , module Predicate.Data.Monoid
+  , module Predicate.Data.Numeric
+  , module Predicate.Data.Ordering
+  , module Predicate.Data.ReadShow
+  , module Predicate.Data.Regex
+  , module Predicate.Data.String
+  , module Predicate.Data.These
+  , module Predicate.Data.Tuple
+ ) where
+import Predicate.Core
+import Predicate.Util
+import Predicate.Data.Char
+import Predicate.Data.Condition
+import Predicate.Data.DateTime
+import Predicate.Data.Either
+import Predicate.Data.Enum
+import Predicate.Data.Extra
+import Predicate.Data.Foldable
+import Predicate.Data.Index
+import Predicate.Data.Iterator
+import Predicate.Data.IO
+import Predicate.Data.Json
+import Predicate.Data.List
+import Predicate.Data.Maybe
+import Predicate.Data.Monoid
+import Predicate.Data.Numeric
+import Predicate.Data.Ordering
+import Predicate.Data.ReadShow
+import Predicate.Data.Regex
+import Predicate.Data.String
+import Predicate.Data.These
+import Predicate.Data.Tuple
src/Predicate/Refined.hs view
@@ -67,7 +67,7 @@ import Control.Lens
 import Data.Functor.Identity (Identity(..))
 import Data.Proxy
-import Control.Monad.Except
+import Control.Monad.Except -- (MonadError, ExceptT(..), runExceptT, throwError, catchError)
 import Control.Monad.Writer (WriterT(..), runWriterT, MonadWriter, tell)
 import Control.Monad.Cont
 import Data.Aeson (ToJSON(..), FromJSON(..))
@@ -199,7 +199,6 @@ 
 -- | 'FromJSON' instance for 'Refined'
 --
--- >>> :set -XOverloadedStrings
 -- >>> import qualified Data.Aeson as A
 -- >>> A.eitherDecode' @(Refined OZ (Between 10 14 Id) Int) "13"
 -- Right (Refined 13)
@@ -301,8 +300,8 @@ 
 -- | binary operation applied to two 'RefinedT' values
 --
--- >>> x = newRefinedT @_ @OAN @(Between 4 12 Id) 4
--- >>> y = newRefinedT @_ @OAN @(Between 4 12 Id) 5
+-- >>> x = newRefinedT @OAN @(Between 4 12 Id) 4
+-- >>> y = newRefinedT @OAN @(Between 4 12 Id) 5
 -- >>> prtRefinedTIO (rapply (+) x y)
 -- === a ===
 -- True 4 <= 4 <= 12
@@ -333,8 +332,8 @@ -- <BLANKLINE>
 -- Refined 9
 --
--- >>> x = newRefinedT @_ @OAN @(Prime Id || Id < 3) 3
--- >>> y = newRefinedT @_ @OAN @(Prime Id || Id < 3) 5
+-- >>> x = newRefinedT @OAN @(Prime Id || Id < 3) 3
+-- >>> y = newRefinedT @OAN @(Prime Id || Id < 3) 5
 -- >>> prtRefinedTIO (rapply (+) x y)
 -- === a ===
 -- True True || False
@@ -377,7 +376,7 @@ -- <BLANKLINE>
 -- failure msg[FalseT]
 --
-rapply :: forall m opts p a opts1 z . (z ~ (opts ':# opts1), OptTC opts1, RefinedC opts p a, Monad m)
+rapply :: forall opts p a opts1 z m . (z ~ (opts ':# opts1), OptTC opts1, RefinedC opts p a, Monad m)
   => (a -> a -> a)
   -> RefinedT m (Refined opts p a)
   -> RefinedT m (Refined opts1 p a)
@@ -391,10 +390,10 @@   Refined y <- mb
   let opts2 = getOptT @z
   tell [setOtherEffects opts2 "=== a `op` b ==="]
-  newRefinedT @_ @_ @p (f x y)
+  newRefinedT @_ @p (f x y)
 
 -- | same as 'rapply' except we already have valid 'Refined' values as input
-rapplyLift :: forall m opts p a . (RefinedC opts p a, Monad m)
+rapplyLift :: forall opts p a m . (RefinedC opts p a, Monad m)
   => (a -> a -> a)
   -> Refined opts p a
   -> Refined opts p a
@@ -403,7 +402,7 @@ 
 -- | attempts to lift a refinement type to another refinement type by way of transformation function
 --   you can control both the predicate and the type
-convertRefinedT :: forall m opts p a p1 a1
+convertRefinedT :: forall opts p a p1 a1 m
   . ( RefinedC opts p1 a1
     , Monad m)
   => (a -> a1)
@@ -411,7 +410,7 @@   -> RefinedT m (Refined opts p1 a1)
 convertRefinedT f ma = do
   Refined a <- ma -- you already got a refined in there so no need to check RefinedC
-  newRefinedT @m @opts @p1 (f a)
+  newRefinedT @opts @p1 (f a)
 
 -- | invokes the callback with the 'Refined' value if \'a\' is valid for the predicate \'p\'
 withRefinedT :: forall opts p m a b
@@ -421,7 +420,7 @@   => a
   -> (Refined opts p a -> RefinedT m b)
   -> RefinedT m b
-withRefinedT a k = newRefinedT @m @opts @p a >>= k
+withRefinedT a k = newRefinedT @opts @p a >>= k
 
 -- | IO version of `withRefinedT`
 withRefinedTIO :: forall opts p m a b
@@ -504,7 +503,7 @@     _ -> throwError $ colorBoolT' o (_tBool tt)
 
 -- | returns a wrapper 'RefinedT' around a possible 'Refined' value if \'a\' is valid for the predicate \'p\'
-newRefinedT :: forall m opts p a
+newRefinedT :: forall opts p a m
   . ( RefinedC opts p a
     , Monad m)
   => a
src/Predicate/Refined1.hs view
@@ -157,7 +157,7 @@ -- Left "Step 1. Initial Conversion(ip) Failed | invalid base 16"
 --
 -- >>> newRefined1 @OL @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Msg "length invalid:" (Len == 4)) @(PrintL 4 "%03d.%03d.%03d.%03d" Id) "198.162.3.1.5"
--- Left "Step 2. False Boolean Check(op) | {length invalid:5 == 4}"
+-- Left "Step 2. False Boolean Check(op) | {length invalid: 5 == 4}"
 --
 -- >>> newRefined1 @OZ @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Guard (PrintF "found length=%d" Len) (Len == 4) >> 'True) @(PrintL 4 "%03d.%03d.%03d.%03d" Id) "198.162.3.1.5"
 -- Left "Step 2. Failed Boolean Check(op) | found length=5"
@@ -170,7 +170,7 @@ -- Right (Refined1 (2019-10-13,41,7))
 --
 -- >>> newRefined1 @OL @(MkDayExtra Id >> 'Just Id) @(Msg "expected a Sunday:" (Thd Id == 7)) @(UnMkDay (Fst Id)) (2019,10,12)
--- Left "Step 2. False Boolean Check(op) | {expected a Sunday:6 == 7}"
+-- Left "Step 2. False Boolean Check(op) | {expected a Sunday: 6 == 7}"
 --
 -- >>> newRefined1 @OZ @(MkDayExtra' (Fst Id) (Snd Id) (Thd Id) >> 'Just Id) @(Guard "expected a Sunday" (Thd Id == 7) >> 'True) @(UnMkDay (Fst Id)) (2019,10,12)
 -- Left "Step 2. Failed Boolean Check(op) | expected a Sunday"
@@ -276,7 +276,7 @@              (do GR.expectP (RL.Ident "Refined1")
                  fld1 <- PCR.reset GR.readPrec
 
-                 let (_ret,mr) = runIdentity $ eval1MSkip @_ @opts @ip @op @fmt fld1
+                 let (_ret,mr) = runIdentity $ eval1MSkip @opts @ip @op @fmt fld1
                  case mr of
                    Nothing -> fail ""
                    Just (Refined1 r1)
@@ -546,7 +546,7 @@   -> RefinedT m b
 withRefined1T = (>>=) . newRefined1TP (Proxy @'(opts,ip,op,fmt,i))
 
-withRefined1TP :: forall m opts ip op fmt i b proxy
+withRefined1TP :: forall opts ip op fmt i b proxy m
   . ( Monad m
     , Refined1C opts ip op fmt i
     , Show (PP ip i)
@@ -587,10 +587,10 @@    -> i
    -> Either String (Refined1 opts ip op fmt i)
 newRefined1P _ x =
-  let (lr,xs) = runIdentity $ unRavelT $ newRefined1T @_ @opts @ip @op @fmt x
+  let (lr,xs) = runIdentity $ unRavelT $ newRefined1T @opts @ip @op @fmt x
   in left (\e -> e ++ (if all null xs then "" else "\n" ++ unlines xs)) lr
 
-newRefined1T :: forall m opts ip op fmt i
+newRefined1T :: forall opts ip op fmt i m
   . ( Refined1C opts ip op fmt i
     , Monad m
     , Show (PP ip i)
@@ -602,16 +602,16 @@ 
 -- | create a wrapped 'Refined1' type
 --
--- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OZ, MkDayExtra Id >> Just Id, GuardSimple (Thd Id == 5) >> 'True, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,1)
+-- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OZ, MkDayExtra Id >> 'Just Id, GuardSimple (Thd Id == 5) >> 'True, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,1)
 -- Refined1 (2019-11-01,44,5)
 --
--- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OL, MkDayExtra Id >> Just Id, Thd Id == 5, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
+-- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OL, MkDayExtra Id >> 'Just Id, Thd Id == 5, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
 -- failure msg[Step 2. False Boolean Check(op) | {6 == 5}]
 --
--- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OL, MkDayExtra Id >> Just Id, Msg "wrong day:" (Thd Id == 5), UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
--- failure msg[Step 2. False Boolean Check(op) | {wrong day:6 == 5}]
+-- >>> prtRefinedTIO $ newRefined1TP (Proxy @'( OL, MkDayExtra Id >> 'Just Id, Msg "wrong day:" (Thd Id == 5), UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
+-- failure msg[Step 2. False Boolean Check(op) | {wrong day: 6 == 5}]
 --
-newRefined1TP :: forall m opts ip op fmt i proxy
+newRefined1TP :: forall opts ip op fmt i proxy m
    . ( Refined1C opts ip op fmt i
      , Monad m
      , Show (PP ip i)
@@ -622,7 +622,7 @@   -> RefinedT m (Refined1 opts ip op fmt i)
 newRefined1TP = newRefined1TPImpl (return . runIdentity)
 
-newRefined1TPIO :: forall m opts ip op fmt i proxy
+newRefined1TPIO :: forall opts ip op fmt i proxy m
    . ( Refined1C opts ip op fmt i
      , MonadIO m
      , Show (PP ip i)
@@ -669,7 +669,7 @@     Just r -> return r
 
 -- | attempts to cast a wrapped 'Refined1' to another 'Refined1' with different predicates
-convertRefined1TP :: forall m opts ip op fmt i ip1 op1 fmt1 i1 .
+convertRefined1TP :: forall opts ip op fmt i ip1 op1 fmt1 i1 m .
   ( Refined1C opts ip1 op1 fmt1 i1
   , Monad m
   , Show (PP ip i)
@@ -686,7 +686,7 @@   return (Refined1 a)
 
 -- | applies a binary operation to two wrapped 'Refined1' parameters
-rapply1 :: forall m opts ip op fmt i .
+rapply1 :: forall opts ip op fmt i m .
   ( Refined1C opts ip op fmt i
   , Monad m
   , Show (PP ip i)
@@ -700,7 +700,7 @@ -- prtRefinedTIO $ rapply1P base16 (+) (newRefined1TP Proxy "ff") (newRefined1TP Proxy "22")
 
 -- | same as 'rapply1' but uses a 5-tuple proxy instead
-rapply1P :: forall m opts ip op fmt i proxy .
+rapply1P :: forall opts ip op fmt i proxy m .
   ( Refined1C opts ip op fmt i
   , Monad m
   , Show (PP ip i)
@@ -787,7 +787,7 @@   -> (RResults1 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined1 opts ip op fmt i))
 eval1 = eval1P Proxy
 
-eval1M :: forall m opts ip op fmt i . (MonadEval m, Refined1C opts ip op fmt i)
+eval1M :: forall opts ip op fmt i m . (MonadEval m, Refined1C opts ip op fmt i)
   => i
   -> m (RResults1 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined1 opts ip op fmt i))
 eval1M i = do
@@ -807,7 +807,7 @@    (Left e,t1) -> pure (RF e t1, Nothing)
 
 -- | creates Refined1 value but skips the initial conversion
-eval1MSkip :: forall m opts ip op fmt i . (MonadEval m, Refined1C opts ip op fmt i)
+eval1MSkip :: forall opts ip op fmt i m . (MonadEval m, Refined1C opts ip op fmt i)
    => PP ip i
    -> m (RResults1 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined1 opts ip op fmt i))
 eval1MSkip a = do
src/Predicate/Refined2.hs view
@@ -127,7 +127,7 @@ -- Left "Step 1. Initial Conversion(ip) Failed | invalid base 16"
 --
 -- >>> newRefined2 @OL @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Msg "length invalid:" (Len == 4)) "198.162.3.1.5"
--- Left "Step 2. False Boolean Check(op) | {length invalid:5 == 4}"
+-- Left "Step 2. False Boolean Check(op) | {length invalid: 5 == 4}"
 --
 -- >>> newRefined2 @OZ @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Guard (PrintF "found length=%d" Len) (Len == 4) >> 'True) "198.162.3.1.5"
 -- Left "Step 2. Failed Boolean Check(op) | found length=5"
@@ -140,7 +140,7 @@ -- Right (Refined2 {r2In = (2019-10-13,41,7), r2Out = (2019,10,13)})
 --
 -- >>> newRefined2 @OL @(MkDayExtra Id >> 'Just Id) @(Msg "expected a Sunday:" (Thd Id == 7)) (2019,10,12)
--- Left "Step 2. False Boolean Check(op) | {expected a Sunday:6 == 7}"
+-- Left "Step 2. False Boolean Check(op) | {expected a Sunday: 6 == 7}"
 --
 -- >>> newRefined2 @OZ @(MkDayExtra' (Fst Id) (Snd Id) (Thd Id) >> 'Just Id) @(Guard "expected a Sunday" (Thd Id == 7) >> 'True) (2019,10,12)
 -- Left "Step 2. Failed Boolean Check(op) | expected a Sunday"
@@ -414,7 +414,7 @@   => i
   -> (Refined2 opts ip op i -> RefinedT m b)
   -> RefinedT m b
-withRefined2TIO = (>>=) . newRefined2TIO @_ @opts @ip @op @i
+withRefined2TIO = (>>=) . newRefined2TIO @opts @ip @op @i
 
 -- | create a 'Refined2' value using a continuation
 --
@@ -457,7 +457,7 @@   -> RefinedT m b
 withRefined2T = (>>=) . newRefined2TP (Proxy @'(opts,ip,op,i))
 
-withRefined2TP :: forall m opts ip op i b proxy
+withRefined2TP :: forall opts ip op i b proxy m
   . ( Monad m
     , Refined2C opts ip op i
     , Show (PP ip i)
@@ -493,21 +493,24 @@       -> i
       -> Either String (Refined2 opts ip op i)
 newRefined2P _ x =
-  let (lr,xs) = runIdentity $ unRavelT $ newRefined2T @_ @opts @ip @op x
+  let (lr,xs) = runIdentity $ unRavelT $ newRefined2T @opts @ip @op x
   in left (\e -> e ++ (if all null xs then "" else "\n" ++ unlines xs)) lr
 
 -- | create a wrapped 'Refined2' type
 --
--- >>> prtRefinedTIO $ newRefined2T @_ @OL @(MkDayExtra Id >> Just Id) @(Thd Id == 5) (2019,11,1)
+-- >>> prtRefinedTIO $ newRefined2T @OL @(MkDayExtra Id >> 'Just Id) @(Thd Id == 5) (2019,11,1)
 -- Refined2 {r2In = (2019-11-01,44,5), r2Out = (2019,11,1)}
 --
--- >>> prtRefinedTIO $ newRefined2T @_ @OL @(MkDayExtra Id >> Just Id) @(Thd Id == 5) (2019,11,2)
+-- >>> prtRefinedTIO $ newRefined2T @OL @(MkDayExtra Id >> 'Just Id) @(Thd Id == 5) (2019,11,2)
 -- failure msg[Step 2. False Boolean Check(op) | {6 == 5}]
 --
--- >>> prtRefinedTIO $ newRefined2T @_ @OL @(MkDayExtra Id >> Just Id) @(Msg "wrong day:" (Thd Id == 5)) (2019,11,2)
--- failure msg[Step 2. False Boolean Check(op) | {wrong day:6 == 5}]
+-- >>> prtRefinedTIO $ newRefined2T @OL @(MkDayExtra Id >> 'Just Id) @(Msg "wrong day:" (Thd Id == 5)) (2019,11,2)
+-- failure msg[Step 2. False Boolean Check(op) | {wrong day: 6 == 5}]
 --
-newRefined2T :: forall m opts ip op i
+-- >>> prtRefinedTIO $ newRefined2TIO @OL @(Hide (Rescan "(\\d+)" Id >> ConcatMap (Snd Id) Id) >> Map (ReadP Int Id) Id) @(Len > 0 && All (0 <..> 0xff) Id) "|23|99|255|254.911."
+-- failure msg[Step 2. False Boolean Check(op) | {True && False | (All(5) i=4 (911 <= 255))}]
+--
+newRefined2T :: forall opts ip op i m
    . ( Refined2C opts ip op i
      , Monad m
      , Show (PP ip i)
@@ -516,7 +519,7 @@ newRefined2T = newRefined2TImpl (return . runIdentity)
 
 -- | create a wrapped 'Refined2' type with an explicit proxy
-newRefined2TP :: forall m opts ip op i proxy
+newRefined2TP :: forall opts ip op i proxy m
    . ( Refined2C opts ip op i
      , Monad m
      , Show (PP ip i)
@@ -526,13 +529,13 @@ newRefined2TP _ = newRefined2TImpl (return . runIdentity)
 
 -- | create a wrapped 'Refined2' type in IO
-newRefined2TIO :: forall m opts ip op i
+newRefined2TIO :: forall opts ip op i m
    . ( Refined2C opts ip op i
      , MonadIO m
      , Show (PP ip i)
     ) => i
       -> RefinedT m (Refined2 opts ip op i)
-newRefined2TIO = newRefined2TImpl liftIO
+newRefined2TIO = newRefined2TImpl @IO @m liftIO
 
 newRefined2TImpl :: forall n m opts ip op i
    . ( Refined2C opts ip op i
@@ -574,7 +577,7 @@   -> i
   -> IO (Either String (Refined2 opts ip op i))
 prtEval2PIO _ i = do
-  x <- eval2M @_ @opts @ip @op i
+  x <- eval2M @opts @ip @op i
   prt2IO @opts x
 
 prtEval2 :: forall opts ip op i
@@ -609,7 +612,7 @@   -> (RResults2 (PP ip i), Maybe (Refined2 opts ip op i))
 eval2 = runIdentity . eval2M
 
-eval2M :: forall m opts ip op i
+eval2M :: forall opts ip op i m
   . ( MonadEval m
     , Refined2C opts ip op i
     )
src/Predicate/Refined3.hs view
@@ -61,6 +61,7 @@   , newRefined3T
   , newRefined3TP
   , newRefined3TPIO
+  , newRefined3TIO
   , withRefined3T
   , withRefined3TIO
   , withRefined3TP
@@ -155,7 +156,7 @@ -- Left "Step 1. Initial Conversion(ip) Failed | invalid base 16"
 --
 -- >>> newRefined3 @OL @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Msg "length invalid:" (Len == 4)) @(PrintL 4 "%03d.%03d.%03d.%03d" Id) "198.162.3.1.5"
--- Left "Step 2. False Boolean Check(op) | {length invalid:5 == 4}"
+-- Left "Step 2. False Boolean Check(op) | {length invalid: 5 == 4}"
 --
 -- >>> newRefined3 @OZ @(Map (ReadP Int Id) (Resplit "\\." Id)) @(Guard (PrintF "found length=%d" Len) (Len == 4) >> 'True) @(PrintL 4 "%03d.%03d.%03d.%03d" Id) "198.162.3.1.5"
 -- Left "Step 2. Failed Boolean Check(op) | found length=5"
@@ -168,7 +169,7 @@ -- Right (Refined3 {r3In = (2019-10-13,41,7), r3Out = (2019,10,13)})
 --
 -- >>> newRefined3 @OL @(MkDayExtra Id >> 'Just Id) @(Msg "expected a Sunday:" (Thd Id == 7)) @(UnMkDay (Fst Id)) (2019,10,12)
--- Left "Step 2. False Boolean Check(op) | {expected a Sunday:6 == 7}"
+-- Left "Step 2. False Boolean Check(op) | {expected a Sunday: 6 == 7}"
 --
 -- >>> newRefined3 @OZ @(MkDayExtra' (Fst Id) (Snd Id) (Thd Id) >> 'Just Id) @(Guard "expected a Sunday" (Thd Id == 7) >> 'True) @(UnMkDay (Fst Id)) (2019,10,12)
 -- Left "Step 2. Failed Boolean Check(op) | expected a Sunday"
@@ -280,7 +281,7 @@                                "r3Out" (PCR.reset GR.readPrec)
                  GR.expectP (RL.Punc "}")
 
-                 let (_ret,mr) = runIdentity $ eval3MSkip @_ @opts @ip @op @fmt fld1
+                 let (_ret,mr) = runIdentity $ eval3MSkip @opts @ip @op @fmt fld1
                  case mr of
                    Nothing -> fail ""
                    Just (Refined3 _r1 r2)
@@ -391,7 +392,7 @@           Just ppi -> do
              let lr = getValLRFromTT (runIdentity (eval @_ (Proxy @fmt) o ppi))
              case lr of
-               Left e -> error $ "formatting failed!! " ++ e
+               Left e -> error $ "genRefined3P: formatting failed!! " ++ e
                Right r -> pure $ unsafeRefined3 ppi r
   in f 0
 
@@ -538,7 +539,7 @@   -> RefinedT m b
 withRefined3T = (>>=) . newRefined3TP (Proxy @'(opts,ip,op,fmt,i))
 
-withRefined3TP :: forall m opts ip op fmt i b proxy
+withRefined3TP :: forall opts ip op fmt i b proxy m
   . ( Monad m
     , Refined3C opts ip op fmt i
     , Show (PP ip i)
@@ -579,21 +580,21 @@    -> i
    -> Either String (Refined3 opts ip op fmt i)
 newRefined3P _ x =
-  let (lr,xs) = runIdentity $ unRavelT $ newRefined3T @_ @opts @ip @op @fmt x
+  let (lr,xs) = runIdentity $ unRavelT $ newRefined3T @opts @ip @op @fmt x
   in left (\e -> e ++ (if all null xs then "" else "\n" ++ unlines xs)) lr
 
 -- | create a wrapped 'Refined3' type
 --
--- >>> prtRefinedTIO $ newRefined3T @_ @OZ @(MkDayExtra Id >> Just Id) @(GuardSimple (Thd Id == 5) >> 'True) @(UnMkDay (Fst Id)) (2019,11,1)
+-- >>> prtRefinedTIO $ newRefined3T @OZ @(MkDayExtra Id >> 'Just Id) @(GuardSimple (Thd Id == 5) >> 'True) @(UnMkDay (Fst Id)) (2019,11,1)
 -- Refined3 {r3In = (2019-11-01,44,5), r3Out = (2019,11,1)}
 --
--- >>> prtRefinedTIO $ newRefined3T @_ @OL @(MkDayExtra Id >> Just Id) @(Thd Id == 5) @(UnMkDay (Fst Id)) (2019,11,2)
+-- >>> prtRefinedTIO $ newRefined3T @OL @(MkDayExtra Id >> 'Just Id) @(Thd Id == 5) @(UnMkDay (Fst Id)) (2019,11,2)
 -- failure msg[Step 2. False Boolean Check(op) | {6 == 5}]
 --
--- >>> prtRefinedTIO $ newRefined3T @_ @OL @(MkDayExtra Id >> Just Id) @(Msg "wrong day:" (Thd Id == 5)) @(UnMkDay (Fst Id)) (2019,11,2)
--- failure msg[Step 2. False Boolean Check(op) | {wrong day:6 == 5}]
+-- >>> prtRefinedTIO $ newRefined3T @OL @(MkDayExtra Id >> 'Just Id) @(Msg "wrong day:" (Thd Id == 5)) @(UnMkDay (Fst Id)) (2019,11,2)
+-- failure msg[Step 2. False Boolean Check(op) | {wrong day: 6 == 5}]
 --
-newRefined3T :: forall m opts ip op fmt i
+newRefined3T :: forall opts ip op fmt i m
   . ( Refined3C opts ip op fmt i
     , Monad m
     , Show (PP ip i)
@@ -605,16 +606,16 @@ 
 -- | create a wrapped 'Refined3' type
 --
--- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OZ, MkDayExtra Id >> Just Id, GuardSimple (Thd Id == 5) >> 'True, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,1)
+-- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OZ, MkDayExtra Id >> 'Just Id, GuardSimple (Thd Id == 5) >> 'True, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,1)
 -- Refined3 {r3In = (2019-11-01,44,5), r3Out = (2019,11,1)}
 --
--- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OL, MkDayExtra Id >> Just Id, Thd Id == 5, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
+-- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OL, MkDayExtra Id >> 'Just Id, Thd Id == 5, UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
 -- failure msg[Step 2. False Boolean Check(op) | {6 == 5}]
 --
--- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OL, MkDayExtra Id >> Just Id, Msg "wrong day:" (Thd Id == 5), UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
--- failure msg[Step 2. False Boolean Check(op) | {wrong day:6 == 5}]
+-- >>> prtRefinedTIO $ newRefined3TP (Proxy @'( OL, MkDayExtra Id >> 'Just Id, Msg "wrong day:" (Thd Id == 5), UnMkDay (Fst Id), (Int,Int,Int))) (2019,11,2)
+-- failure msg[Step 2. False Boolean Check(op) | {wrong day: 6 == 5}]
 --
-newRefined3TP :: forall m opts ip op fmt i proxy
+newRefined3TP :: forall opts ip op fmt i proxy m
    . ( Refined3C opts ip op fmt i
      , Monad m
      , Show (PP ip i)
@@ -625,11 +626,28 @@   -> RefinedT m (Refined3 opts ip op fmt i)
 newRefined3TP = newRefined3TPImpl (return . runIdentity)
 
-newRefined3TPIO :: forall m opts ip op fmt i proxy
+-- | wrap a Refined3 type using RefinedT and IO
+--
+-- >>> prtRefinedTIO $ newRefined3TIO @OL @(Hide (Rescan "(\\d+)" Id >> ConcatMap (Snd Id) Id) >> Map (ReadP Int Id) Id) @(Len > 0 && All (0 <..> 0xff) Id) @(ShowP Id) "|23|99|255|254.911."
+-- failure msg[Step 2. False Boolean Check(op) | {True && False | (All(5) i=4 (911 <= 255))}]
+--
+-- >>> unRavelT $ newRefined3TIO @OL @(Hide (Rescan "(\\d+)" Id >> ConcatMap (Snd Id) Id) >> Map (ReadP Int Id) Id) @(Len > 0 && All (0 <..> 0xff) Id) @(ShowP Id) "|23|99|255|254.911."
+-- (Left "Step 2. False Boolean Check(op) | {True && False | (All(5) i=4 (911 <= 255))}",[""])
+--
+newRefined3TIO :: forall opts ip op fmt i m
    . ( Refined3C opts ip op fmt i
      , MonadIO m
      , Show (PP ip i)
      , Show i)
+  => i
+  -> RefinedT m (Refined3 opts ip op fmt i)
+newRefined3TIO = newRefined3TPImpl liftIO Proxy
+
+newRefined3TPIO :: forall opts ip op fmt i proxy m
+   . ( Refined3C opts ip op fmt i
+     , MonadIO m
+     , Show (PP ip i)
+     , Show i)
   => proxy '(opts,ip,op,fmt,i)
   -> i
   -> RefinedT m (Refined3 opts ip op fmt i)
@@ -646,7 +664,7 @@    -> i
    -> RefinedT m (Refined3 opts ip op fmt i)
 newRefined3TPImpl f _ i = do
-  (ret,mr) <- f $ eval3M  i
+  (ret,mr) <- f $ eval3M i
   let m3 = prt3Impl (getOptT @opts) ret
   tell [m3Long m3]
   case mr of
@@ -673,7 +691,7 @@     Just r -> return r
 
 -- | attempts to cast a wrapped 'Refined3' to another 'Refined3' with different predicates
-convertRefined3TP :: forall m opts ip op fmt i ip1 op1 fmt1 i1 .
+convertRefined3TP :: forall opts ip op fmt i ip1 op1 fmt1 i1 m .
   ( Refined3C opts ip op fmt i
   , Refined3C opts ip1 op1 fmt1 i1
   , Monad m
@@ -691,7 +709,7 @@   return (Refined3 a b)
 
 -- | applies a binary operation to two wrapped 'Refined3' parameters
-rapply3 :: forall m opts ip op fmt i .
+rapply3 :: forall opts ip op fmt i m .
   ( Refined3C opts ip op fmt i
   , Monad m
   , Show (PP ip i)
@@ -705,7 +723,7 @@ -- prtRefinedTIO $ rapply3P base16 (+) (newRefined3TP Proxy "ff") (newRefined3TP Proxy "22")
 
 -- | same as 'rapply3' but uses a 5-tuple proxy instead
-rapply3P :: forall m opts ip op fmt i proxy .
+rapply3P :: forall opts ip op fmt i proxy m .
   ( Refined3C opts ip op fmt i
   , Monad m
   , Show (PP ip i)
@@ -796,7 +814,7 @@   -> (RResults3 (PP ip i) (PP fmt (PP ip i)), Maybe (Refined3 opts ip op fmt i))
 eval3P _ = runIdentity . eval3M
 
-eval3M :: forall m opts ip op fmt i
+eval3M :: forall opts ip op fmt i m
   . ( MonadEval m
     , Refined3C opts ip op fmt i
     )
@@ -819,7 +837,7 @@    (Left e,t1) -> pure (RF e t1, Nothing)
 
 -- | creates Refined3 value but skips the initial conversion
-eval3MSkip :: forall m opts ip op fmt i
+eval3MSkip :: forall opts ip op fmt i m
   . ( MonadEval m
     , Refined3C opts ip op fmt i
     )
src/Predicate/Util.hs view
@@ -16,9 +16,7 @@ {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ViewPatterns #-}
 {-# LANGUAGE ConstraintKinds #-}
-{-# LANGUAGE MultiWayIf #-}
 {-# LANGUAGE StandaloneDeriving #-}
 {-# LANGUAGE NoStarIsType #-}
 {-# LANGUAGE FunctionalDependencies #-}
@@ -138,6 +136,14 @@   , type (%&)
   , type (<%>)
   , AnyT
+  , ExtractAFromList
+  , ExtractAFromTA
+  , MaybeT
+  , LeftT
+  , RightT
+  , ThisT
+  , ThatT
+  , TheseT
 
  -- ** extract values from the type level
   , nat
@@ -153,8 +159,8 @@ 
  -- ** printing methods
   , prtTreePure
-  , prettyRational
   , formatOMsg
+  , prtTree
 
  -- ** boolean methods
   , (~>)
@@ -186,10 +192,11 @@   , pureTryTestPred
   , isPrime
   , unlessNull
+  , badLength
+  , showIndex
 
     ) where
 import qualified GHC.TypeNats as GN
-import Data.Ratio
 import GHC.TypeLits (Symbol,Nat,KnownSymbol,KnownNat,ErrorMessage((:$$:),(:<>:)))
 import qualified GHC.TypeLits as GL
 import Control.Lens
@@ -266,7 +273,7 @@ deriving instance Show a => Show (BoolT a)
 deriving instance Eq a => Eq (BoolT a)
 
--- | extracts the 'BoolT a' constructors from the typelevel
+-- | extracts the \'BoolT a\' constructors from the typelevel
 class GetBoolT a (x :: BoolT a) | x -> a where
   getBoolT :: Either Bool Bool
 instance GetBoolT Bool 'TrueT where
@@ -371,7 +378,7 @@ hh :: TT w -> Holder
 hh = Holder
 
--- | see 'getValueLRImpl' : add more detail to the tree if there are errors
+-- | add more detail to the tree if there are errors
 getValueLR :: POpts
            -> String
            -> TT a
@@ -413,6 +420,7 @@   HKD Identity a = a
   HKD f a = f a
 
+-- | final set of options using Identity
 type POpts = HOpts Identity
 
 -- | customizable options for running a typelevel expression
@@ -1085,10 +1093,10 @@ colorBoolT o r =
   let f = colorMe o (r ^. boolT2P)
   in case r of
-      FailT e -> f "Error" <> " " <> e
+      FailT e -> f "Error " <> e
       TrueT -> f "True"
       FalseT -> f "False"
-      PresentT x -> f "Present" <> " " <> show x
+      PresentT x -> f "Present " <> show x
 
 colorBoolT' :: Show a
    => POpts
@@ -1097,10 +1105,10 @@ colorBoolT' o r =
   let f = colorMe o (r ^. boolT2P)
   in case r of
-      FailT e -> f "FailT" <> " " <> e
+      FailT e -> f "FailT " <> e
       TrueT -> f "TrueT"
       FalseT -> f "FalseT"
-      PresentT x -> f "PresentT" <> " " <> show x
+      PresentT x -> f "PresentT " <> show x
 
 -- | colors the result of the predicate based on the current color palette
 colorMe ::
@@ -1112,6 +1120,7 @@   let (_, PColor f) = if oNoColor o then nocolor else oColor o
   in f b s
 
+-- | override PresentP case if there is no tree ie lite or zero mode
 fixLite :: forall a . Show a
    => POpts
    -> a
@@ -1121,6 +1130,7 @@   | hasNoTree opts = fixPresentP opts (t ^. root . pBool) a <> "\n"
   | otherwise = prtTreePure opts t
 
+-- | override PresentP case with long name
 fixPresentP :: Show a
   => POpts
   -> BoolP
@@ -1128,9 +1138,10 @@   -> String
 fixPresentP opts bp a =
   case bp of
-    PresentP -> colorMe opts PresentP "Present" <> " " <> show a
+    PresentP -> colorMe opts PresentP "Present " <> show a
     _ -> colorBoolP opts bp
 
+-- | display tree
 prtTreePure ::
      POpts
   -> Tree PE
@@ -1139,10 +1150,11 @@   | hasNoTree opts = colorBoolP opts (t ^. root . pBool)
   | otherwise = showImpl opts $ fmap (toNodeString opts) t
 
+-- | extract message part from tree
 topMessage :: TT a -> String
 topMessage pp =
   let s = pp ^. tString
-  in if null s then "" else "(" <> s <> ")"
+  in unlessNull s $ "(" <> s <> ")"
 
 showImpl :: POpts
          -> Tree String
@@ -1152,15 +1164,11 @@     Unicode -> TV.showTree
     Ansi -> drawTree -- to drop the last newline else we have to make sure that everywhere else has that newline: eg fixLite
 
-prettyRational :: Rational -> String
-prettyRational (numerator &&& denominator -> (n,d)) =
-  if | n == 0 -> "0"
-     | d == 1 -> show n
-     | otherwise -> show n <> " / " <> show d
-
+-- | render numbered tree
 fixit :: ((Int, x), TT a) -> TT a
-fixit ((i, _), t) = prefixMsg ("i=" <> show i <> ":") t
+fixit ((i, _), t) = prefixMsg ("i=" <> show i <> ": ") t
 
+-- | prefix text in front of tString
 prefixMsg :: String -> TT a -> TT a
 prefixMsg msg t =
    t & tString %~ (msg <>)
@@ -1173,12 +1181,14 @@ showTK :: forall r . Typeable r => String
 showTK = show (typeRep (Proxy @r))
 
+-- | pretty print 'Ordering'
 prettyOrd :: Ordering -> String
 prettyOrd = \case
               LT -> "<"
               EQ -> "="
               GT -> ">"
 
+-- | Repeat an expression n times
 type family RepeatT (n :: Nat) (p :: k) :: [k] where
   RepeatT 0 p = GL.TypeError ('GL.Text "RepeatT is not defined for zero")
   RepeatT 1 p = p ': '[]
@@ -1187,16 +1197,18 @@ type s <%> t = GL.AppendSymbol s t
 infixr 7 <%>
 
+-- | Intersperse a symbol inside a list of symbols
 type family IntersperseT (s :: Symbol) (xs :: [Symbol]) :: Symbol where
   IntersperseT s '[] = ""
   IntersperseT s '[x] = x
   IntersperseT s (x ': y ': xs) = x <%> s <%> IntersperseT s (y ': xs)
 
+-- | length of a type level list
 type family LenT (xs :: [k]) :: Nat where
   LenT '[] = 0
   LenT (x ': xs) = 1 GN.+ LenT xs
 
--- | takes a flat n-tuple and creates a reversed inductive tuple. see 'Predicate.Prelude.PrintT'
+-- | takes a flat n-tuple and creates a reversed inductive tuple. see 'Predicate.Data.ReadShow.PrintT'
 --
 -- >>> inductTupleC (123,'x',False,"abc")
 -- ("abc",(False,('x',(123,()))))
@@ -1244,7 +1256,7 @@   type InductTupleP (a,b,c,d,e,f,g,h,i,j,k,l) = (l,(k,(j,(i,(h,(g,(f,(e,(d,(c,(b,(a,()))))))))))))
   inductTupleC (a,b,c,d,e,f,g,h,i,j,k,l) = (l,(k,(j,(i,(h,(g,(f,(e,(d,(c,(b,(a,()))))))))))))
 
--- | takes a list and converts to a reversed inductive tuple. see 'Predicate.Prelude.PrintL'
+-- | takes a list and converts to a reversed inductive tuple. see 'Predicate.Data.ReadShow.PrintL'
 --
 -- >>> inductListC @4 [10,12,13,1]
 -- (1,(13,(12,(10,()))))
@@ -1319,24 +1331,28 @@ 
 infixr 9 %&
 
+-- | 'flip' at the type level
 type family FlipT (d :: k1 -> k -> k2) (p :: k) (q :: k1) :: k2 where
   FlipT d p q = d q p
 
+-- | 'if' at the type level
 type family IfT (b :: Bool) (t :: k) (f :: k) :: k where
   -- IfT b x x = x -- todo: benefit? now it needs to eval both sides
   IfT 'True t f = t
   IfT 'False t f = f
 
+-- | 'sum' at the type level for a list of 'Nat'
 type family SumT (ns :: [Nat]) :: Nat where
   SumT '[] = 0
   SumT (n ': ns) = n GL.+ SumT ns
 
 -- only works if you use ADTs not type synonyms
+-- | 'map' at the type level
 type family MapT (f :: k -> k1) (xs :: [k]) :: [k1] where
   MapT f '[] = '[]
   MapT f (x ': xs) = f x ': MapT f xs
 
--- | Extract \'a\' from a list like container
+-- | Extract \'a\' from a list-like container
 type family ConsT s where
   ConsT [a] = a
   ConsT (ZipList a) = a
@@ -1355,12 +1371,14 @@   catchitNF :: (E.Exception e, NFData a) => a -> m (Either String a)
   liftEval :: m a -> IO a
 
+-- | 'Identity' instance for evaluating the expression
 instance MonadEval Identity where
   runIO _ = Identity Nothing
   catchit v = Identity $ unsafePerformIO $ catchit @IO @E.SomeException v
   catchitNF v = Identity $ unsafePerformIO $ catchitNF @IO @E.SomeException v
   liftEval = return . runIdentity
 
+-- | 'IO' instance for evaluating the expression
 instance MonadEval IO where
   runIO ioa = Just <$> ioa
   catchit v = E.evaluate (Right $! v) `E.catch` (\(E.SomeException e) -> pure $ Left ("IO e=" <> show e))
@@ -1388,6 +1406,7 @@ errorInProgram :: HasCallStack => String -> x
 errorInProgram s = error $ "programmer error:" <> s
 
+-- | read a field and value using 'ReadPrec' parser
 readField :: String -> ReadPrec a -> ReadPrec a
 readField fieldName readVal = do
         GR.expectP (L.Ident fieldName)
@@ -1466,6 +1485,7 @@ 
 infixr 6 :#
 
+-- | extract options from the typelevel
 class OptTC (k :: OptT) where
    getOptT' :: POptsL
 instance KnownNat n => OptTC ('OWidth n) where
@@ -1542,6 +1562,7 @@ instance OptTC 'OUV where
    getOptT' = getOptT' @('OAV ':# 'OUnicode)
 
+-- | combinations of options
 type OZ = 'OAnsi ':# 'OColorOff ':# 'OZero
 type OL = 'OAnsi ':# 'OColorOff ':# 'OLite ':# 'OWidth 200
 type OAN = 'OAnsi ':# 'OColorOff ':# 'ONormal ':# 'OWidth 100
@@ -1573,26 +1594,36 @@ getOptT :: forall o . OptTC o => POpts
 getOptT = reifyOpts (getOptT' @o)
 
+-- | extract \'opts\' part of 4 tuple from the type level for use with 'Predicate.Refined2.Refined2'
 type family T4_1 x where
-  T4_1 '(a,_,_,_) = a
+  T4_1 '(opts,_,_,_) = opts
+-- | extract \'ip\' part of 4 tuple from the type level for use with 'Predicate.Refined2.Refined2'
 type family T4_2 x where
-  T4_2 '(_,b,_,_) = b
+  T4_2 '(_,ip,_,_) = ip
+-- | extract \'op\' part of 4 tuple from the type level for use with 'Predicate.Refined2.Refined2'
 type family T4_3 x where
-  T4_3 '(_,_,c,_) = c
+  T4_3 '(_,_,op,_) = op
+-- | extract \'i\' part of 4 tuple from the type level for use with 'Predicate.Refined2.Refined2'
 type family T4_4 x where
-  T4_4 '(_,_,_,d) = d
+  T4_4 '(_,_,_,i) = i
 
+-- | extract \'opts\' part of 5 tuple from the type level for use with 'Predicate.Refined3.Refined3'
 type family T5_1 x where
-  T5_1 '(a,_,_,_,_) = a
+  T5_1 '(opts,_,_,_,_) = opts
+-- | extract \'ip\' part of 5 tuple from the type level for use with 'Predicate.Refined3.Refined3'
 type family T5_2 x where
-  T5_2 '(_,b,_,_,_) = b
+  T5_2 '(_,ip,_,_,_) = ip
+-- | extract \'op\' part of 5 tuple from the type level for use with 'Predicate.Refined3.Refined3'
 type family T5_3 x where
-  T5_3 '(_,_,c,_,_) = c
+  T5_3 '(_,_,op,_,_) = op
+-- | extract \'fmt\' part of 5 tuple from the type level for use with 'Predicate.Refined3.Refined3'
 type family T5_4 x where
-  T5_4 '(_,_,_,d,_) = d
+  T5_4 '(_,_,_,fmt,_) = fmt
+-- | extract \'i\' part of 5 tuple from the type level for use with 'Predicate.Refined3.Refined3'
 type family T5_5 x where
-  T5_5 '(_,_,_,_,e) = e
+  T5_5 '(_,_,_,_,i) = i
 
+-- | deal with possible recursion on a list
 chkSize :: Foldable t
    => POpts
    -> String
@@ -1605,18 +1636,21 @@     (_,[]) -> Right ()
     (_,_:_) -> Left $ mkNode opts (FailT (msg0 <> " list size exceeded")) ("max is " ++ show mx) hhs
 
+-- | pretty print a message
 formatOMsg :: POpts -> String -> String
 formatOMsg o suffix =
   case oMsg o of
     [] -> mempty
     s@(_:_) -> intercalate " | " (map (setOtherEffects o) s) <> suffix
 
+-- | override options for 'DZero' so we dont lose error information
 subopts :: POpts -> POpts
 subopts opts =
   case oDebug opts of
     DZero -> opts { oDebug = DLite }
     _ -> opts
 
+-- | render a string for messages using optional color and underline
 setOtherEffects :: POpts -> String -> String
 setOtherEffects o =
   if oNoColor o then id
@@ -1648,9 +1682,10 @@ isPrime :: Int -> Bool
 isPrime n = n==2 || n>2 && all ((> 0).rem n) (2:[3,5 .. floor . sqrt @Double . fromIntegral $ n+1])
 
+-- | represents any kind
 type family AnyT :: k where {}
 
--- | mconcat  options at the type level
+-- | mconcat 'OptT' options at the type level
 --
 -- >>> x = getOptT @(OptTT '[ 'OMsg "test", 'ORecursion 123, OU, OL, 'OMsg "field2"])
 -- >>> oMsg x
@@ -1662,7 +1697,91 @@   OptTT '[] = 'OEmpty
   OptTT (x ': xs) = x ':# OptTT xs
 
+-- | convenience method for optional display
 unlessNull :: (Foldable t, Monoid m) => t a -> m -> m
 unlessNull t m | null t = mempty
                | otherwise = m
 
+-- | message to display when the length of a foldable is exceeded
+badLength :: Foldable t
+          => t a
+          -> Int
+          -> String
+badLength as n = ":invalid length(" <> show (length as) <> ") expected " ++ show n
+
+-- | type family to extract \'a\' from \'t a\'
+type family ExtractAFromTA (ta :: Type) :: Type where
+  ExtractAFromTA (t a) = a
+  ExtractAFromTA z = GL.TypeError (
+      'GL.Text "ExtractAFromTA: expected (t a) but found something else"
+      ':$$: 'GL.Text "t a = "
+      ':<>: 'GL.ShowType z)
+
+-- todo: get ExtractAFromList failure to fire if wrong Type
+-- | type family to extract \'a\' from a list of \'a\'
+type family ExtractAFromList (as :: Type) :: Type where
+  ExtractAFromList [a] = a
+  ExtractAFromList z = GL.TypeError (
+      'GL.Text "ExtractAFromList: expected [a] but found something else"
+      ':$$: 'GL.Text "as = "
+      ':<>: 'GL.ShowType z)
+
+type family MaybeT mb where
+  MaybeT (Maybe a) = a
+  MaybeT o = GL.TypeError (
+      'GL.Text "MaybeT: expected 'Maybe a' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+
+type family LeftT lr where
+  LeftT (Either a _) = a
+  LeftT o = GL.TypeError (
+      'GL.Text "LeftT: expected 'Either a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+type family RightT lr where
+  RightT (Either a b) = b
+  RightT o = GL.TypeError (
+      'GL.Text "RightT: expected 'Either a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+type family ThisT lr where
+  ThisT (These a b) = a
+  ThisT o = GL.TypeError (
+      'GL.Text "ThisT: expected 'These a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+type family ThatT lr where
+  ThatT (These a b) = b
+  ThatT o = GL.TypeError (
+      'GL.Text "ThatT: expected 'These a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+type family TheseT lr where
+  TheseT (These a b) = (a,b)
+  TheseT o = GL.TypeError (
+      'GL.Text "TheseT: expected 'These a b' "
+      ':$$: 'GL.Text "o = "
+      ':<>: 'GL.ShowType o)
+
+prtTree :: Show x => POpts -> TT x -> String
+prtTree opts pp =
+  let r = pp ^. tBool
+  in case oDebug opts of
+       DZero -> ""
+       DLite ->
+             formatOMsg opts " >>> "
+          <> colorBoolT opts r
+          <> " "
+          <> topMessage pp
+          <> "\n"
+       _ -> formatOMsg opts "\n"
+         <> prtTreePure opts (fromTT pp)
+
+showIndex :: (Show i, Num i) => i -> String
+showIndex i = show (i+0)
src/Predicate/Util_TH.hs view
@@ -231,7 +231,7 @@   => i
   -> TH.Q (TH.TExp (Refined2 opts ip op i))
 refined2THIO i = do
-  x <- TH.runIO (eval2M @_ @opts @ip @op i)
+  x <- TH.runIO (eval2M @opts @ip @op i)
   case x of
     (_, Just a) -> TH.TExp <$> TH.lift a
     (ret, Nothing) -> fail $ show $ prt2Impl (getOptT @opts) ret
@@ -304,7 +304,7 @@   => i
   -> TH.Q (TH.TExp (Refined3 opts ip op fmt i))
 refined3THIO i = do
-  x <- TH.runIO (eval3M @_ @opts @ip @op @fmt i)
+  x <- TH.runIO (eval3M @opts @ip @op @fmt i)
   case x of
     (_, Just a) -> TH.TExp <$> TH.lift a
     (ret, Nothing) -> fail $ show $ prt3Impl (getOptT @opts) ret
test/TestJson.hs view
@@ -85,7 +85,7 @@ type NameR2 (opts :: OptT) = R.Refined opts (Name2 >> 'True) String
 type Name2 =
           Uncons
-       >> 'Just Id
+       >> Just'
        >> Guard (PrintF "not upper first(%c)" Id) IsUpper
       *** Guard (PrintF "not lower rest(%s)" Id) IsLowerAll
 
test/TestPredicate.hs view
@@ -15,7 +15,6 @@ {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE NoStarIsType #-}
 module TestPredicate where
-import Safe
 import TastyExtras
 import Test.Tasty
 import Test.Tasty.HUnit
@@ -27,10 +26,6 @@ import Control.Lens
 import Data.Time
 import Text.Show.Functions ()
-import Data.Functor.Compose
-import qualified Data.Map.Strict as M
-import qualified Data.Set as S
-import qualified Data.Text as T
 import qualified Data.Monoid as MM
 import qualified Data.Semigroup as SG
 import Data.These
@@ -45,411 +40,47 @@ allTests =
   [ expectPE (PresentT [False,True,True,False]) $ pl @'[Gt 5, Lt 9, Same 4, W 'False] 4
   , expectPE (PresentT [21,19,20,40,60,2]) $ pl @'[Succ Id, Pred Id, Id, Id + Id, Id * 3, Id `Mod` 3] 20
-  , expectPE (PresentT LT) $ pl @("aa" ==! Id) "aaaa"
-  , expectPE FalseT $ pl @(FromEnum ("aa" ==! Id) >> Same 1) "aaaa"
-  , expectPE (PresentT (Right 1)) $ pl @(HeadDef 'False Id +++ Id) (Right @[Bool] 1) -- need @[Bool] cos we said 'False!
-  , expectPE (PresentT (Left True)) $ pl @(HeadDef 'False Id +++ Id) (Left @_ @Int [True,False]) -- need @[Bool] cos we said 'False!
-  , expectPE (PresentT (Right True)) $ pl @(Not Id +++ Id) (Right True)
-  , expectPE (PresentT (4,4)) $ pl @(Dup >> Id) 4
-  , expectPE (PresentT (Right 12)) $ pl @(Not Id +++ Id) (Right 12)
-  , expectPE (PresentT (Right 1)) $ pl @(HeadDef () Id +++ Id) (Right @[()] 1) -- breaks otherwise: Id says () -> () so has to be a list of [()]
-  , expectPE (PresentT (Right 1)) $ pl @(HeadDef () Id +++ Id) (Right @[()] 1) -- this breaks! cos Left doesnt have a type
-  , expectPE FalseT $ pl @(Not (Fst Id >> Len <= 6)) ([2..7],True)
-  , expectPE TrueT $ pl @(Fst Id >> Len <= 6) ([2..7],True)
-  , expectPE TrueT $ pl @(Length (Fst Id) <= 6) ([2..7],True)
-  , expectPE TrueT $ pl @(Fst Id >> (Len <= 6)) ([2..7],True)
-  , expectPE FalseT $ pl @(HeadDef 12 (Fst Id) >> Le 6) ([],True)
-  , expectPE TrueT $ pl @(HeadDef 1 (Fst Id) >> Le 6) ([],True)
-  , expectPE (FailT "Head(empty)") $ pl @(Head (Fst Id) >> Le 6) ([]::[Int], True)
-  , expectPE FalseT $ pl @(HeadDef 10 (Fst Id) >> Le 6) ([],True)
-  , expectPE (FailT "zz") $ pl @(HeadFail "zz" (Fst Id) >> Le 6) ([],True)
-  , expectPE (FailT "failed1") $ pl @((HeadFail "failed1" (Fst Id) >> Le 6) || 'False) ([],True)
-  , expectPE TrueT $ pl @((Fst Id >> HeadFail "failed2" Id >> Le (6 -% 1)) || 'False) ([-9],True)
-  , expectPE (FailT "failed3") $ pl @((Fst Id >> Failt _ "failed3" >> Le (6 -% 1)) || 'False) ([-5],True)
-  , expectPE TrueT $ pl @(MaybeIn 'True Id) (Nothing @Bool) -- need @() else breaks
-  , expectPE (PresentT 10) $ pl @(MaybeIn (Failt _ "failed4") Id) (Just 10)
-  , expectPE (PresentT 10) $ pl @(Just Id) (Just 10)
-  , expectPE FalseT $ pl @(MaybeIn 'False Id) (Nothing @Bool) -- breaks otherwise
-  , expectPE FalseT $ pl @(Id > "xx") "abc"
-  , expectPE TrueT $ pl @(Id > "aa") "abc"
-  , expectPE TrueT $ pl @(Gt 4) 5
-  , expectPE TrueT $ pl @(Any (Gt 3) (Fst Id)) ([10,12,3,5],"ss")
-  , expectPE FalseT $ pl @(All (Gt 3) (Fst Id)) ([10,12,3,5],"ss")
   , expectPE (PresentT [False,False,False,True]) $ pl @(Map (Mod Id 3) (Fst Id) >> Map (Gt 1) Id) ([10,12,3,5],"ss")
-  , expectPE (PresentT (12,5)) $ pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Id) ([10,12,3,5],"ss")
-  , expectPE FalseT $ pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Fst Id < Snd Id) ([10,12,3,5],"ss")
-  , expectPE TrueT $ pl @(Fst Id >> Dup >> (Ix 1 (Failp "failed5") *** Ix 3 (Failp "failed5")) >> Fst Id > Snd Id) ([10,12,3,5],"ss")
-  , expectPE TrueT $ pl @(Fst Id > Snd Id) (True,False)
-  , expectPE FalseT $ pl @(Fst Id == Snd Id) (True,False)
-  , expectPE TrueT $ pl @(Not Id*** Id >> Fst Id == Snd Id) (True,False)
-  , expectPE FalseT $ pl @(Snd Id >> Len &&& Ix 3 (Failp "someval1") >> Fst Id == Snd Id) ('x',[1..5])
-  , expectPE FalseT $ pl @(Snd Id >> Len &&& Ix 3 (Failp "someval2") >> Fst Id < Snd Id) ('x',[1..5])
-  , expectPE TrueT $ pl @(Snd Id >> Len &&& Ix 3 (Failp "someval3") >> Fst Id > Snd Id) ('x',[1..5])
-  , expectPE FalseT $ pl @(Snd Id >> SplitAt 2 Id >> Len *** Len >> Fst Id > Snd Id) ('x',[1..5])
-  , expectPE FalseT $ pl @(Any (Same 2) Id) [1,4,5]
-  , expectPE TrueT $ pl @(Any (Same 2) Id) [1,4,5,2,1]
-  , expectPE TrueT $ pl @(Elem Id '[2,3,4]) 2
-  , expectPE FalseT $ pl @(Elem Id '[2,3,4]) 6
-  , expectPE TrueT $ pl @(Elem Id '[13 % 2]) 6.5
-  , expectPE TrueT $ pl @(Elem Id '[13 % 2, 12 % 1]) 6.5
-  , expectPE FalseT $ pl @(Elem Id '[13 % 2, 12 % 1]) 6
-  , expectPE (FailT "lhs") $ pl @(Map Len Id >> Ix 3 (Failp "lhs") &&& Ix 0 5 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE FalseT $ pl @(Map Len Id >> Ix 0 (Failp "lhs") &&& Ix 1 5 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE (FailT "rhs") $ pl @(Map Len Id >> Ix 1 (Failp "lhs") &&& Ix 3 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE (FailT "lhs") $ pl @(Map Len Id >> Ix 10 (Failp "lhs") &&& Ix 1 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE (FailT "rhs") $ pl @(Map Len Id >> Ix 0 (Failp "lhs") &&& Ix 10 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE FalseT $ pl @(Map Len Id >> Ix 10 3 &&& Ix 1 (Failp "rhs") >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE FalseT $ pl @(Map Len Id >> Ix 3 3 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE FalseT $ pl @(Map Len Id >> Ix 10 3 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE FalseT $ pl @(Map Len Id >> Ix 10 5 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE TrueT $ pl @(Map Len Id >> Ix 10 2 &&& Ix 1 4 >> Fst Id == Snd Id) [[1..4],[4..5]]
-  , expectPE (PresentT ([1],[2,3,4,5])) $ pl @(Partition (Lt 2) Id >> Id) [1,2,3,4,5]
-  , expectPE (PresentT [1,2,3]) $ pl @(MaybeIn MEmptyP Id) (Just [1,2,3])
-  , expectPE (PresentT []) $ pl @(MaybeIn MEmptyP Id) (Nothing @[Int])
-  , expectPE (FailT "'Just found Nothing") $ pl @('Just (FailS "someval")) (Nothing @()) -- breaks otherwise
-  , expectPE (PresentT (4,4)) $ pl @Dup 4
-  , expectPE (PresentT 3) $ pl @(Last Id) [1,2,3]
-  , expectPE (PresentT 123) $ pl @(Just Id >> Id) (Just 123)
-  , expectPE (FailT "Asdf") $ pl @(HeadFail "Asdf" Id) ([] :: [()]) -- breaks otherwise
-  , expectPE (FailT "Head(empty)") $ pl @(Head Id) ([] :: [Int])
-  , expectPE (FailT "Head(empty)") $ pl @(Head Id) ([] :: [Double])
-  , expectPE (FailT "Succ bounded") $ pl @(SuccB' Id) GT
-  , expectPE (PresentT LT) $ pl @(SuccB 'LT Id) GT
-  , expectPE (PresentT EQ) $ pl @(SuccB 'GT Id) LT
-  , expectPE (PresentT EQ) $ pl @(SuccB' Id) LT
-  , expectPE (FailT "Pred bounded") $ pl @(PredB' Id) LT
-  , expectPE (PresentT GT) $ pl @(PredB 'GT Id) LT
-  , expectPE (PresentT EQ) $ pl @(PredB 'LT Id) GT
-  , expectPE (PresentT EQ) $ pl @(PredB' Id) GT
-  , expectPE (FailT "ToEnum bounded") $ pl @(ToEnumBFail Ordering) 44
-  , expectPE (PresentT LT) $ pl @(ToEnumBDef Ordering 'LT) 123
-  , expectPE (PresentT EQ) $ pl @(ToEnumBDef Ordering 'GT) 1
-  , expectPE (PresentT EQ) $ pl @(ToEnumBFail Ordering) 1
-  , expectPE (PresentT 11) $ pl @(Succ Id) 10
-  , expectPE (FailT "Succ IO e=Prelude.Enum.Bool.succ: bad argument") $ pl @(Succ Id) True -- captures the exception
-  , expectPE (PresentT ([4,5,6,7,8,9,10],[1,2,3])) $ pl @(Partition (Gt 3) Id) [1..10]
-  , expectPE (PresentT ([2,4,6],[1,3,5])) $ pl @(Partition Even Id) [1..6]
-  , expectPE TrueT $ pl @(Partition Even Id >> Null *** (Len > 4) >> Fst Id == Snd Id) [1..6]
   , expectPE (PresentT 5) $ pl @(Snd Id >> Snd Id >> Snd Id >> Snd Id >> Id) (9,(1,(2,(3,5))))
-  , expectPE (FailT "ExitWhen") $ pl @(HeadFail "failedn" Id &&& (Len == 1 >> ExitWhen "ExitWhen" Id) >> Fst Id) [3]
-  , expectPE (PresentT 3) $ pl @(Head Id &&& (Len == 1 >> Not Id >> ExitWhen "ExitWhen" Id) >> Fst Id) [3]
-  , expectPE (PresentT 3) $ pl @(Head Id &&& (Len == 1 >> ExitWhen "ExitWhen" (Not Id)) >> Fst Id) [3]
-  , expectPE (FailT "ExitWhen") $ pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id) [3,1]
-  , expectPE (PresentT 3) $ pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id) [3]
-  , expectPE TrueT $ pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id >> Gt (20 -% 1 )) [3]
-  , expectPE FalseT $ pl @(ExitWhen "ExitWhen" (Len /= 1) >> Head Id >> Gt (20 -% 1 )) [-23]
   , expectPE (PresentT (-1.0)) $ pl @(Negate Id >> Dup >> First (Succ Id) >> Swap >> Fst Id - Snd Id) 4
-  , expectPE (PresentT (Right 12)) $ pl @(Not Id +++ Id) (Right @Bool 12)
-  , expectPE (PresentT CGt) $ pl @(FromEnum ("aa" ==! Id) >> ToEnum OrderingP Id) "aaaa"
   , expectPE (PresentT False) $ pl @(Msg "someval4" (Gt 4 >> Id)) 4
   , expectPE (PresentT ()) $ pl @(Snd Id >> Snd Id >> Snd Id >> Snd Id >> Id) (1,('a',(3,(True,()))))
-  , expectPE TrueT $ pl @(Re "\\d{4}-\\d{3}" Id) "1234-123"
-  , expectPE FalseT $ pl @(Re "\\d{4}-\\d{3}" Id) "1234-1x3"
-  , expectPE TrueT $ pl @(Re' '[ 'Caseless, 'Dotall ] "ab" Id) "aB"
-  , expectPE TrueT $ pl @(Re' '[ 'Caseless, 'Dotall ] "ab." Id) "aB\n"
-  , expectPE FalseT $ pl @(Re' '[ 'Caseless ] "ab." Id) "aB\n"
-  , expectPE TrueT $ pl @(Re "(?i)ab" Id) "aB" -- runtime [use 'Caseless instead]
-  , expectPE FalseT $ pl @(Re "ab" Id) "aB"
-  , expectPE (PresentT [("aB",["B"]),("cd",["d"])]) $ pl @(Rescan ".(.)" Id) "aBcd"
-  , expectPE (PresentT [14,12,10,4,2]) $ pl @(SortOnDesc Id Id) [10,4,2,12,14]
-  , expectPE (PresentT [2,4,10,12,14]) $ pl @(SortOn Id Id) [10,4,2,12,14]
-  , expectPE (PresentT [14,12,10,4,2]) $ pl @(SortOn (Negate Id) Id) [10,4,2,12,14]
-  , expectPE (PresentT [('a',4),('a',14),('b',2),('c',10),('d',12),('z',1)]) $ pl @(SortOn (Fst Id) Id) (zip "cabdaz" [10,4,2,12,14,1])
-  , expectPE (FailT "asdf(4)") $ pl @(SortOn (FailS "asdf") Id) [10,4,2,12,14]
-  , expectPE TrueT $ pl @(Min &&& Max >> Id >> Fst Id < Snd Id) [10,4,2,12,14]
-  , expectPE (FailT "ExitWhen") $ pl @(Partition (ExitWhen "ExitWhen" (Gt 10) >> Gt 2) Id) [1..11]
-  , expectPE (PresentT [False,False,True,True,True]) $ pl @(Map (ExitWhen "ExitWhen" (Gt 10) >> Gt 2) Id) [1..5]
-  , expectPE (PresentT ([1,2],[3,4,5,6,7,8,9,10,11])) $ pl @(Break (Gt 2) Id) [1..11]
-  , expectPE (PresentT ([1,2,3],[4,5,6,7,8,9,10,11])) $ pl @(Span (Lt 4) Id) [1..11]
-  , expectPE (PresentT [GT,GT,LT,EQ]) $ pl @(Pairs >> Map (First (Succ Id >> Succ Id) >> Fst Id ==! Snd Id) Id) [1,2,3,6,8]
-  , expectPE TrueT $ pl @(Re "^\\d{1,3}(?:\\.\\d{1,3}){3}$" Id) "123.1.1.21"
-  , expectPE (PresentT [("123.",["."]),("8.",["."]),("99.",["."]),("21",[])]) $ pl @(Rescan "\\d{1,3}(\\.)?" Id) "123.8.99.21"
-  , expectPE (PresentT 117) $ pl @(MaybeIn (Failp "err") (Succ Id)) (Just 116)
-  , expectPE (PresentT 99) $ pl @(MaybeIn 99 (Succ Id)) (Nothing @Int)
-  , expectPE (FailT "someval") $ pl @(MaybeIn (Failp "someval") (Succ Id)) (Nothing @())
-  , expectPE TrueT $ pl @(MaybeIn 'True 'False) (Nothing @())
-  , expectPE FalseT $ pl @(MaybeIn 'True 'False) (Just "aa")
-  , expectPE (PresentT LT) $ pl @(MaybeIn MEmptyP (Fst Id ==! Snd Id)) (Just ('x','z'))
-  , expectPE (PresentT EQ) $ pl @(MaybeIn MEmptyP (Fst Id ==! Snd Id)) (Nothing @(Char,Char))
-  , expectPE TrueT $ pl @('True ||| 'False) (Left @_ @() "someval")
-  , expectPE FalseT $ pl @('True ||| 'False) (Right @() "someval")
-  , expectPE (PresentT 123) $ pl @('Left Id) (Left 123)
-  , expectPE (FailT "'Left found Right") $ pl @('Left Id) (Right @() 123)
-  , expectPE (PresentT 123) $ pl @('Right Id) (Right 123)
-  , expectPE (FailT "'Right found Left") $ pl @('Right Id) (Left @_ @() 123)
-  , expectPE (PresentT ["1","2","3"]) $ pl @(MaybeIn MEmptyP (Ones (ShowP Id))) (Just 123)
-  , expectPE (PresentT []) $ pl @(MaybeIn MEmptyP (Ones (ShowP Id))) (Nothing @String)
-  , expectPE (PresentT "124") $ pl @(ShowP (Succ Id) ||| ShowP Id ) (Left @_ @() 123)
-  , expectPE (PresentT "True") $ pl @(ShowP (Succ Id) ||| ShowP Id) (Right @Int True)
-  , expectPE (PresentT (123 % 4)) $ pl @(ReadP Rational Id) "123 % 4"
-  , expectPE (FailT "ReadP Ratio Integer (x123 % 4)") $ pl @(ReadP Rational Id) "x123 % 4"
-  , expectPE (PresentT "") $ pl @('Proxy >> MEmptyP) "abc"
-  , expectPE (PresentT ["a","b","c"]) $ pl @(MEmptyT _ ||| Ones Id) (Right @() "abc")
-  , expectPE (PresentT []) $ pl @(MEmptyT _ ||| Ones Id) (Left @_ @[String] ["ab"])
-  , expectPE (PresentT ["a","b"]) $ pl @(MaybeIn MEmptyP (Ones Id)) (Just @String "ab")
-  , expectPE (PresentT []) $ pl @(MaybeIn MEmptyP (Ones Id)) (Nothing @String)
-  , expectPE (PresentT (True, 13)) $ pl @(Not (IsNothing Id) &&& (Just Id >> Id + 12)) (Just 1)
-  , expectPE (FailT "Just(empty)") $ pl @(Not (IsNothing Id) &&& (Just Id >> Id + 12)) Nothing
   , expectPE (PresentT True) $ pl @(Thd Id >> Fst Id) (1,2,(True,4))
   , expectPE (PresentT True) $ pl @(Fst (Thd Id)) (1,2,(True,4))
-  , expectPE (PresentT 'd') $ pl @(Id !! 3) ("asfd" :: T.Text)
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! 4) ("asfd" :: T.Text)
-  , expectPE (PresentT "dfsa") $ pl @ReverseL ("asfd" :: T.Text)
-  , expectPE (PresentT (Left "asfd")) $ pl @Swap (Right @() "asfd") -- @() else breaks: ok in ghci
-  , expectPE (PresentT ("asfd",12)) $ pl @Swap (12,"asfd")
-  , expectPE (PresentT (Just ('a',"sfd"))) $ pl @Uncons ("asfd" :: T.Text)
-  , expectPE (PresentT Nothing) $ pl @Uncons ("" :: T.Text)
-  , expectPE (PresentT (Just ("asf",'d'))) $ pl @Unsnoc ("asfd" :: T.Text)
-  , expectPE (PresentT Nothing) $ pl @Unsnoc ("" :: T.Text)
-  , expectPE FalseT $ pl @IsEmpty ("failed11" :: T.Text)
-  , expectPE TrueT $ pl @IsEmpty ("" :: T.Text)
-  , expectPE (PresentT 14) $ pl @(Unwrap Id >> Succ Id) (SG.Sum 13)
-  , expectPE (PresentT 4) $ pl @(MEmptyT (SG.Sum _) >> Unwrap Id >> Id + 4) ()
-  , expectPE (PresentT (SG.Sum 13)) $ pl @(Wrap (SG.Sum _) Id) 13
-  , expectPE (PresentT "a") $ pl @(Id !! MEmptyT _) (Just "a")
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! MEmptyT _) (Nothing @()) -- had to add @() to keep this happy: ghci is fine
-  , expectPE (PresentT 'a') $ pl @(Id !! 0) ('a','b','c')
-  , expectPE (FailT "err") $ pl @(Id !! Failt _ "err") ('a','b','c')
-  , expectPE (PresentT 3) $ pl @(Id !! "d") (M.fromList $ zip (map (:[]) "abcd") [0 ..])
-  , expectPE (PresentT 3) $ pl @(Id !! Head "d") (M.fromList $ zip "abcd" [0 ..]) -- had to String (instead of _) to keep this happy: ghci is fine
-  , expectPE (PresentT ()) $ pl @(Id !! Head "d") (S.fromList "abcd") -- had to String (instead of _) to keep this happy: ghci is fine
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! HeadFail "failedn" "e") (S.fromList "abcd") -- had to String (instead of _) to keep this happy: ghci is fine
-  , expectPE (PresentT 13.345) $ pl @(Guard "regex failed" (Re "^\\d+(?:\\.\\d+)?$" Id) >> ReadP Double Id) "13.345"
-  , expectPE (PresentT 13) $ pl @(Guard "regex failed" (Re "^\\d+(?:\\.\\d+)?$" Id) >> ReadP Double Id) "13"
-  , expectPE (FailT "regex failed") $ pl @(ExitWhen "regex failed" (Not (Re "^\\d+(?:\\.\\d+)?$" Id)) >> ReadP Double Id) "-13.4"
-  , expectPE (PresentT GT) $ pl @(FoldN 2 Id (Succ Id)) LT
-  , expectPE (FailT "Succ IO e=Prelude.Enum.Ordering.succ: bad argument") $ pl @(FoldN 30 Id (Succ Id)) LT
-  , expectPE (PresentT 'g') $ pl @(FoldN 6 Id (Succ Id)) 'a'
-  , expectPE (PresentT '[') $ pl @(FoldN 6 Id (Pred Id)) 'a'
-  , expectPE (FailT "Regex failed to compile") $ pl @(Re "\\d{4}\\" Id) "ayx"
-  , expectPE (PresentT LT) $ pl @(FoldN 0 Id (Succ Id)) LT
-  , expectPE (PresentT LT) $ pl @(FoldN 2 Id (Succ Id) >> FoldN 2 Id (Pred Id)) LT
-  , expectPE (PresentT ["2","2"]) $ pl @(Map (Fst Id) (Rescan "." (ShowP Id)) >> Filter (Same "2") Id) 12324
-  , expectPE (PresentT [LT,LT,LT,GT,EQ,LT]) $ pl @((Ones Id << ShowP Id) >> Map (Fst Id ==! Snd Id) Pairs) 1234223
-  , expectPE (PresentT [(0,'a'),(1,'b'),(2,'c'),(3,'d')]) $ pl @(IToList _ Id) ("abcd" :: String)
-  , expectPE (PresentT "abcd") $ pl @ToList (M.fromList $ zip [0..] "abcd")
-  , expectPE (PresentT [123]) $ pl @ToList (Just 123)
-  , expectPE (FailT "failed20") $ pl @(MaybeIn (Failp "failed20") 'False) (Nothing @Int)
-  , expectPE (FailT "failed21") $ pl @(MaybeIn ('False >> FailS "failed21") 'False) (Nothing @Double)
-  , expectPE (FailT "err") $ pl @(MaybeIn (Failp "err") Id) (Nothing @Int)
-  , expectPE (FailT "err") $ pl @(MaybeIn (Failp "err") Id) (Nothing @())
-  , expectPE (PresentT [(0,'a'),(1,'b'),(2,'c'),(3,'d')]) $ pl @(IToList _ Id) (M.fromList $ itoList ("abcd" :: String))
-  , expectPE (PresentT [(1,'a'),(2,'b'),(3,'c'),(4,'d'),(99,'e'),(99,'f'),(99,'g')]) $ pl @(ZipL 99 Id "abcdefg") [1..4]
-  , expectPE (FailT "Zip(3,7) length mismatch") $ pl @(Zip "abc" Id) [1..7]
-  , expectPE (PresentT [(1 % 1,'a'),(2 % 1,'b'),(3 % 1,'c'),(99 % 4,'d'),(99 % 4,'e')]) $ pl @(ZipL (99 % 4) '[1 % 1 , 2 % 1 , 3 % 1 ] Id) "abcde"
-
-  , expectPE (PresentT [("X",'a'),("X",'b'),("X",'c'),("X",'d')]) $ pl @(ZipL "X" (EmptyT _ Id) Id) ("abcd" :: String)
-
-  , expectPE (FailT "ZipR(0,4) rhs would be truncated") $ pl @(ZipR (Char1 "Y") (EmptyT _ Id) Id) "abcd"
+  , expectPE (FailT "failed3") $ pl @((Fst Id >> Failt _ "failed3" >> Le (6 -% 1)) || 'False) ([-5],True)
+  , expectPE (PresentT [(-999) % 1,10 % 1,20 % 1,(-999) % 1,30 % 1]) $ pl @(Map (Wrap (MM.First _) Id &&& (Pure Maybe (999 -% 1 ) >> Wrap (MM.First _) Id)) Id >> Map SapA Id >> Map ('Just (Unwrap Id)) Id) [Nothing,Just 10,Just 20,Nothing,Just 30]
 
-  , expectPE (PresentT [9,2,7,4]) $ pl @ToList (M.fromList (zip ['a'..] [9,2,7,4]))
-  , expectPE (PresentT [(0,9),(1,2),(2,7),(3,4)]) $ pl @(IToList _ Id) [9,2,7,4]
-  , expectPE (PresentT [('a',9),('b',2),('c',7),('d',4)]) $ pl @(IToList _ Id) (M.fromList (zip ['a'..] [9,2,7,4]))
-  , expectPE (PresentT [((),234)]) $ pl @(IToList _ Id) (Just 234)
-  , expectPE (PresentT []) $ pl @(IToList _ Id) (Nothing @Double)
-  , expectPE (PresentT (-4,5)) $ pl @(DivMod (Negate Id) 7) 23
-  , expectPE (PresentT (-3,-2)) $ pl @(QuotRem (Negate Id) 7) 23
   , expectPE (PresentT (True,3.4)) $ pl @(Thd Id >> Snd Id >> Fst Id) (1,'a',('x',((True,3.4),999)))
   , expectPE (PresentT (True,3.4)) $ pl @(Fst (Snd (Thd Id))) (1,'a',('x',((True,3.4),999)))
-  , expectPE (PresentT 7) $ pl @(Fst Id) (7,999.12)
-  , expectPE (PresentT (M.fromList [(1,'a')])) $ pl @(MaybeIn MEmptyP Id) (Just (M.fromList [(1,'a')]))
-  , expectPE (PresentT M.empty) $ pl @(MaybeIn MEmptyP Id) (Nothing @(M.Map () ()))
-  , expectPE (PresentT [("1",["1"]),("2",["2"]),("3",["3"]),("4",["4"])]) $ pl @(Rescan "(\\d)+?" Id) "1234"
-  , expectPE (PresentT [("1234",["4"])]) $ pl @(Rescan "(\\d)+" Id) "1234"
-  , expectPE (PresentT [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])]) $ pl @(Rescan "(\\d{1,3})(\\.(\\d{1,3}))+?" Id) "1.2.3.4" -- overcapturing
-  , expectPE (PresentT [("1234",["4"])]) $ pl @(Rescan "^(\\d)+?$" Id) "1234"
-  , expectPE (PresentT [("1.2",["1",".2","2"]),("3.4",["3",".4","4"])]) $ pl @(Rescan "(\\d{1,3})(\\.(\\d{1,3}))+?" Id) "1.2.3.4"
-  , expectPE (PresentT ["123","2","3","5","6"]) $ pl @(Resplit "\\." Id) "123.2.3.5.6"
-  , expectPE (PresentT [("1.2",["1","2"]),("3.4",["3","4"])]) $ pl @(Rescan "(\\d{1,3})(?:\\.(\\d{1,3}))+?" Id) "1.2.3.4" -- bizzare!
-  , expectPE (PresentT [("1.2.3.4",["1","2","3","4"])]) $ pl @(Rescan "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$" Id) "1.2.3.4" -- this is good!
   , expectPE (PresentT [13,16,17]) $ pl @(Guard "err" (Len > 2) >> Map (Succ Id) Id) [12,15,16]
-  , expectPE (FailT "err found len=3") $ pl @(Guard (PrintF "err found len=%d" Len) (Len > 5) >> Map (Succ Id) Id) [12,15,16]
-  , expectPE (FailT "PrintF (IO e=printf: bad formatting char 'd')") $ pl @(PrintF "someval %d" Id) ("!23"::String)
-  , expectPE (PresentT [12,0,1,13,0,1,14,0,1,15,0,1,16]) $ pl @(Intercalate (Fst Id) (Snd Id)) ([0,1], [12,13,14,15,16])
-  , expectPE (PresentT [12,-5,13,-5,14,-5,15,-5,16]) $ pl @((Pure [] (Negate Len) &&& Id) >> Intercalate (Fst Id) (Snd Id)) [12,13,14,15,16]
-  , expectPE (PresentT [13,16,17]) $ pl @(If (Len > 2) (Map (Succ Id) Id) (FailS "someval")) [12,15,16]
-  , expectPE (PresentT [13,16,17]) $ pl @(Guard "oops" (Len > 2) >> Map (Succ Id) Id) [12,15,16]
-  , expectPE (FailT "err") $ pl @(ExitWhen "err" (Len > 2) >> Map (Succ Id) Id) [12,15,16]
-  , expectPE (PresentT [13]) $ pl @(ExitWhen "err" (Len > 2) >> Map (Succ Id) Id) [12]
-  , expectPE (FailT "err") $ pl @(Guard "err" (Len > 2) >> Map (Succ Id) Id) [12]
-  , expectPE (PresentT 12) $ pl @(OneP Id) [12]
-  , expectPE (FailT "OneP 5 elements") $ pl @(OneP Id) [1..5]
-  , expectPE (FailT "OneP empty") $ pl @(OneP Id) ([] ::[()])
-  , expectPE (FailT "err(8)") $ pl @(Map (If (Lt 3) 'True (Failt _ "err")) Id) [1..10]
-  , expectPE (FailT "someval(8)") $ pl @(Map (If (Lt 3) 'True (Failt _ "someval")) Id) [1..10]
-  , expectPE (PresentT [True,True,False,False,False]) $ pl @(Map (If (Lt 3) 'True 'False) Id) [1..5]
-  , expectPE (PresentT ["a","b","c"]) $ pl @(MaybeIn MEmptyP (Ones Id)) (Just @String "abc")
-  , expectPE (FailT "someval") $ pl @(Guard "someval" (Len == 2) >> (ShowP Id &&& Id)) ([] :: [Int])
-  , expectPE (PresentT ([2,3],"[2,3]")) $ pl @(Guard "someval" (Len == 2) >> (Id &&& ShowP Id)) [2,3]
-  , expectPE (FailT "someval") $ pl @(Guard "someval" (Len == 2) >> (ShowP Id &&& Id)) [2,3,4]
   , expectPE (PresentT 55) $ pl @(Map (Wrap (SG.Sum _) Id) Id >> MConcat Id >> Unwrap Id) [1..10]
-  , expectPE (PresentT True) $ pl @(EitherIn (Not Id) Id) (Right @Bool True)
-  , expectPE FalseT $ pl @(EitherIn (Not Id) Id) (Left @_ @Bool True)
-  , expectPE FalseT $ pl @(Re "^\\d+$" Id) "123\nx"
-  , expectPE TrueT $ pl @(Re "(?m)^\\d+$" Id) "123\nx" -- (?m) anchors match beginning/end of line instead of whole string
-  , expectPE (PresentT (Just 'x')) $ pl @(Pure Maybe Id) 'x'
-  , expectPE (PresentT (Right @() 'x')) $ pl @(Pure (Either _) Id) 'x'
-  , expectPE (PresentT Nothing) $ pl @(MEmptyT (Maybe ())) 'x'
-  , expectPE (PresentT (Left @_ @() 'x')) $ pl @(Pure (Either _) Id >> Swap) 'x'
-  , expectPE (PresentT (Left 'x')) $ pl @(Pure (Either ()) Id >> Swap) 'x'
-  , expectPE (PresentT (SG.Sum 52)) $ pl @(STimes 4 Id) (SG.Sum 13)
-  , expectPE (PresentT (SG.Sum 52)) $ pl @(Wrap (SG.Sum _) Id >> STimes 4 Id) 13
-  , expectPE (PresentT 52) $ pl @(FoldMap (SG.Sum _) Id) [14,8,17,13]
-  , expectPE (PresentT 17) $ pl @(FoldMap (SG.Max _) Id) [14 :: Int,8,17,13] -- cos Bounded!
-  , expectPE FalseT $ pl @(Catch (Re "\\d+(" Id) 'False) "123"
-  , expectPE TrueT $ pl @(Catch (Re "\\d+" Id) 'False) "123"
-  , expectPE (PresentT 3) $ pl @(Id !! Head "d") (M.fromList $ zip "abcd" [0 ..])   -- use Char1 "d" instead of "d" >> Head
-  , expectPE (PresentT 10) $ pl @(Id !! MEmptyT _) (Just 10)
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! MEmptyT _) (Nothing @())
-  , expectPE TrueT $ pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) [1..20]
-  , expectPE FalseT $ pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) [1..19]
-  , expectPE TrueT $ pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) || (FoldMap (SG.Sum _) Id >> Gt 200)) []
-  , expectPE (PresentT (False, 210)) $ pl @((Len >> (Elem Id '[4,7,1] || (Mod Id 3 >> Same 0))) &&& FoldMap (SG.Sum _) Id) [1..20]
-  , expectPE (PresentT 'g') $ pl @(Id !! 6) ['a'..'z']
-  , expectPE (PresentT ([141,214,125,1,2,3333],(False,False))) $ pl @(Map (ReadP Int Id) (Resplit "\\." Id) >> '(Id, '(Len == 4, All (Between 0 255 Id) Id))) "141.214.125.1.2.3333"
-  , expectPE (PresentT ([141,214,125,1,2,6],(False,True))) $ pl @(Map (ReadP Int Id) (Resplit "\\." Id) >> Id &&& ((Len == 4) &&& All (Between 0 255 Id) Id)) "141.214.125.1.2.6"
-  , expectPE (FailT "ReadP Int ()") $ pl @(Resplit "\\." Id >> Map (ReadP Int Id) Id >> Id &&& ((Len == 4) &&& All (Between 0 255 Id) Id)) "141.214.125."
   , expectPE (PresentT 9) $ pl @((Wrap _ Id *** Wrap (SG.Sum _) Id) >> SapA >> Unwrap Id) (4,5)
   , expectPE (PresentT (SG.Sum 9)) $ pl @((Wrap _ Id *** Wrap _ Id) >> SapA) (4,5)
-  , expectPE (PresentT 9) $ pl @(SapA' (SG.Sum _) >> Unwrap Id) (4,5)
-  , expectPE (PresentT "abcde") $ pl @(ScanNA (Succ Id)) (4,'a')
-  , expectPE (PresentT ["abcd","bcd","cd","d",""]) $ pl @(ScanNA (Tail Id)) (4,"abcd" :: String)
-  , expectPE (PresentT ["abcd","bcd","cd","d",""]) $ pl @(Len &&& Id >> ScanNA (Tail Id)) "abcd"
-  , expectPE (PresentT ["abcd","bcd","cd","d",""]) $ pl @Tails ("abcd" :: String)
-  , expectPE (PresentT (-4,-2)) $ pl @(DivMod (Fst Id) (Snd Id)) (10,-3)
-  , expectPE (PresentT (-3,1)) $ pl @(QuotRem (Fst Id) (Snd Id)) (10,-3)
-  , expectPE (FailT "DivMod zero denominator") $ pl @(DivMod (Fst Id) (Snd Id)) (10,0)
-  , expectPE (PresentT 'd') $ pl @(Snd Id !! Fst Id) (3,"abcde" :: String)
-  , expectPE (FailT "(!!) index not found") $ pl @(Snd Id !! Fst Id) (4,[9,8])
-  , expectPE (PresentT 'c') $ pl @(2 &&& Id >> Snd Id !! Fst Id) ("abcdef" :: String)
-  , expectPE (PresentT 'f') $ pl @((Len >> Pred Id) &&& Id >> Snd Id !! Fst Id) "abcdef"
   , expectPE (FailT "len is bad") $ pl @Ip6Test "FE80::203:Baff:FE77:326FF"
   , expectPE (FailT "not a hex") $ pl @Ip6Test "FE80::203:Baff:GE77:326F"
   , expectPE (FailT "count is bad") $ pl @Ip6Test "FE80::203:Baff:FE77:326F:::::"
-  , expectPE (PresentT 65504) $ pl @(ReadBase Int 16 Id) "fFe0"
-  , expectPE (PresentT "ffe0") $ pl @(ShowBase 16 Id) 65504
-  , expectPE (FailT "invalid base 22") $ pl @(ReadBase Int 22 Id) "zzz"
-  , expectPE (PresentT ("ffe0","fFe0")) $ pl @((ReadBase Int 16 Id &&& Id) >> First (ShowBase 16 Id)) "fFe0"
-  , expectPE FalseT $ pl @(Id == "Abc") "abc"
-  , expectPE TrueT $ pl @("Abc" ==~ Id) "abc"
-  , expectPE (PresentT LT) $ pl @("Abc" ==! Id) "abc"
-  , expectPE (PresentT EQ) $ pl @("Abc" ===~ Id) "abc"
-  , expectPE (PresentT 'd') $ pl @(Id !! 3) ('a','b','c','d','e')
-  , expectPE (PresentT 99) $ pl @(Id !! "s") $ M.fromList [("t",1), ("s", 20), ("s", 99)]
-  , expectPE (PresentT 1) $ pl @(Head Id) [1,2,3]
-  , expectPE (PresentT (Just (1,[2,3,4,5]))) $ pl @Uncons [1..5] -- with Typeable would need to specify the type of [1..5]
-  , expectPE (PresentT (Just ([1,2,3,4],5))) $ pl @Unsnoc [1..5]
-  , expectPE (PresentT [(0,1),(1,2),(2,3),(3,4),(4,5)]) $ pl @(IToList _ Id) [1..5]
-  , expectPE (PresentT [(0,'a'),(1,'b'),(2,'c')]) $ pl @(IToList _ Id) ['a','b','c']
-  , expectPE (PresentT [1,2,3,8,8]) $ pl @(PadR 5 8 Id) [1..3]
-  , expectPE (PresentT [1,2,3,4,5]) $ pl @(PadR 5 0 Id) [1..5]
-  , expectPE (PresentT [1,2,3,4,5,6]) $ pl @(PadR 5 0 Id) [1..6]
-  , expectPE (PresentT [0,0,1,2,3]) $ pl @(PadL 5 0 Id) [1..3]
-  , expectPE (PresentT []) $ pl @(Catch (Resplit "\\d+(" Id) (Snd Id >> MEmptyP)) "123"
-  , expectPE (FailT "someval(8)") $ pl @(Map (Guard "someval" (Lt 3) >> 'True) Id) [1::Int ..10]
-  , expectPE (FailT "(3 < 3) | (4 < 3) | (5 < 3) | (6 < 3) | (7 < 3) | (8 < 3) | (9 < 3) | (10 < 3)") $ pl @(Map (GuardSimple (Lt 3) >> 'True) Id) [1::Int .. 10]
-  , expectPE FalseT $ pl @(All (Lt 3) Id) [1::Int .. 10]
-  , expectPE (PresentT [True,True,True,True,True,True,True,True,True,True]) $ pl @(Map (GuardSimple (Ge 1) >> 'True) Id) [1::Int .. 10]
-  , expectPE (PresentT [4,5,6]) $ pl @(ScanN 2 Id (Succ Id)) 4
-  , expectPE (PresentT [4,4,4,4,4,4]) $ pl @(ScanN 5 Id Id) 4
   , expectPE (PresentT [1,2,3,244]) $ pl @(Rescan Ip4RE Id >> OneP Id >> Map (ReadBase Int 10 Id) (Snd Id) >> Ip4op) "1.2.3.244"
   , expectPE (FailT "octet 1 out of range 0-255 found 256") $ pl @(Rescan Ip4RE Id >> OneP Id >> Map (ReadBase Int 10 Id) (Snd Id) >> Ip4op) "1.256.3.244"
   , expectPE (FailT "Guards:invalid length(5) expected 4") $ pl @(Rescan "(\\d+)\\.?" Id >> ConcatMap (Snd Id) Id >> Map (ReadBase Int 10 Id) Id >> Ip4op) "1.22.244.66.77"
-  , expectPE (PresentT (SG.Sum 123)) $ pl @(JustDef (MEmptyT _) Id) (Just (SG.Sum 123))
-  , expectPE (PresentT (SG.Sum 0)) $ pl @(JustDef (MEmptyT _) Id) (Nothing @(SG.Sum _))
-  , expectPE (PresentT (636 % 5)) $ pl @((ToRational 123 &&& Id) >> Fst Id + Snd Id) 4.2
-  , expectPE (PresentT 127) $ pl @((123 &&& Id) >> Fst Id + Snd Id) 4
   , expectPE (PresentT 256) $ pl @(Rescan "(?i)^\\\\x([0-9a-f]{2})$" Id >> OneP Id >> Snd Id >> OneP Id >> ReadBase Int 16 Id >> Succ Id) "\\xfF"
   , expectPE (PresentT 256) $ pl @(Rescan "(?i)^\\\\x(.{2})$" Id >> OneP Id >> Snd Id >> OneP Id >> ReadBase Int 16 Id >> Succ Id) "\\xfF"
   , expectPE (PresentT (("fF",(255,"ff")),False)) $ pl @(Rescan "(?i)^\\\\x([0-9a-f]{2})$" Id >> OneP Id >> Snd Id >> OneP Id >> (Id &&& (ReadBase Int 16 Id >> (Id &&& ShowBase 16 Id))) >> (Id &&& ((Id *** Snd Id) >> Fst Id == Snd Id))) "\\xfF"
-  , expectPE (PresentT [1,2,4,0]) $ pl @(Do '[Succ Id,Id,ShowP Id,Ones Id,Map (ReadBase Int 8 Id) Id]) 1239
-  , expectPE (FailT "invalid base 8") $ pl @(Do '[Pred Id,Id,ShowP Id,Ones Id,Map (ReadBase Int 8 Id) Id]) 1239
-  , expectPE (PresentT 47) $ pl @(ReadBase Int 2 Id) "101111"
-  , expectPE (PresentT [LT,EQ,GT,EQ,EQ,EQ,EQ,EQ,EQ,EQ]) $ pl @(ScanN 2 Id (Succ Id) >> PadR 10 (MEmptyT Ordering) Id) LT
-  , expectPE (PresentT 12) $ pl @('This Id) (This 12)
-  , expectPE (FailT "'This found That") $ pl @('This Id) (That @() 12)
-  , expectPE (PresentT (SG.Sum 12)) $ pl @(ThisDef (MEmptyT _) Id) (This @_ @() (SG.Sum 12))
-  , expectPE (PresentT ()) $ pl @(ThisDef (MEmptyT _) Id) (That 12)
-  , expectPE (PresentT (SG.Sum 12)) $ pl @(ThisFail "sdf" Id) (This @_ @() (SG.Sum 12))
-  , expectPE (FailT "sdf") $ pl @(ThisFail "sdf" Id) (That @() (SG.Sum 12))
-  , expectPE (FailT "sdf") $ pl @(ThisFail "sdf" Id) (That @Int 12)
-  , expectPE (PresentT "this") $ pl @(TheseIn "this" "that" "these") (This @_ @() (SG.Sum 12))
-  , expectPE FalseT $ pl @(IsThese Id) (That @() (SG.Sum 12))
-  , expectPE TrueT $ pl @(IsThese Id) (These 1 (SG.Sum 12))
-  , expectPE (PresentT ("Ab",13)) $ pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (These "Ab" 13)
-  , expectPE (PresentT ("Ab",999)) $ pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (This "Ab")
-  , expectPE (PresentT ("no value",13)) $ pl @(TheseIn (Id &&& 999) ("no value" &&& Id) Id) (That 13)
-  , expectPE (PresentT "wxydef") $ pl @(ZipThese (Fst Id) (Snd Id) >> Map (TheseIn Id Id (Fst Id)) Id) (['w'..'y'],['a'..'f'])
-  , expectPE (PresentT [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])]) $ pl @(Rescan "([[:xdigit:]]{2})" Id) "wfeb12az"
-  -- anchored means it has to start at the beginning: can have junk on the end which we cant detect but at least we know it starts at beginning
-  , expectPE (FailT "Regex no results") $ pl @(Rescan' '[ 'Anchored ] "([[:xdigit:]]{2})" Id) "wfeb12az"
-  , expectPE (PresentT [('s',1),('d',2),('f',3),('x',4),('x',5)]) $ pl @(("sdf" &&& Id) >> ZipThese (Fst Id) (Snd Id) >> Map (TheseIn (Id &&& 0) (Head "x" &&& Id) Id) Id) [1..5]
-  , expectPE (PresentT "abc") $ pl @"abc" ()
-  , expectPE FalseT $ pl @(Not 'True) ()
-  , expectPE TrueT $ pl @'True ()
-  , expectPE FalseT $ pl @'False ()
-  , expectPE (PresentT LT) $ pl @'LT ()
-  , expectPE (PresentT 123) $ pl @123 ()
-  , expectPE (PresentT (4,("sadf",LT))) $ pl @(4 &&& "sadf" &&& 'LT) ()
-  , expectPE (PresentT (4,("sadf",LT))) $ pl @(4 *** "sadf" *** 'LT) ('x',("abv",[1]))
-  , expectPE (PresentT 6) $ pl @(Do '[4,5,6]) ()
-  , expectPE (PresentT "hhhhh") $ pl @(Do '["abc", "Def", "ggg", "hhhhh"]) ()
-  , expectPE (PresentT GT) $ pl @(Do '[ 'LT, 'EQ, 'GT ]) ()
-  , expectPE (PresentT (-3 % 1)) $ pl @(Do '[4 % 4,22 % 1 ,12 -% 4]) ()
-  , expectPE (PresentT [10,2,5]) $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 0 11 Id, Between 1 4 Id,Between 3 5 Id]) [10::Int,2,5]
   , expectPE (PresentT [31,11,1999]) $ pl @(Rescan DdmmyyyyRE Id >> OneP Id >> Map (ReadBase Int 10 Id) (Snd Id) >> Ddmmyyyyop) "31-11-1999"
-  , expectPE (PresentT [31,11,1999]) $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11,1999::Int]
-  , expectPE (FailT "Guards:invalid length(2) expected 3") $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11::Int]
-  , expectPE (FailT "guard(1) 13 is out of range") $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,13,1999::Int]
-  , expectPE (FailT "guard(0) 0 is out of range") $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [0,44,1999::Int]
-  , expectPE (PresentT (fromGregorian 1999 11 30)) $ pl @(ReadP Day Id) "1999-11-30"
-  , expectPE (FailT "ReadP Day (1999-02-29)") $ pl @(ReadP Day Id) "1999-02-29"
-  , expectPE (PresentT (TimeOfDay 14 59 20)) $ pl @(ReadP TimeOfDay Id) "14:59:20"
---  , expectPE (PresentT (TimeOfDay 26 61 61)) $ pl @(ReadP TimeOfDay Id) "26:61:61" -- yep: this is valid in <=time-1.8 ! need to do your own validation
-  , expectPE (FailT "ParseTimeP TimeOfDay (%H:%M%S) failed to parse") $ pl @(ParseTimeP TimeOfDay "%H:%M%S" Id) "14:04:61"
   , expectPE (PresentT (TimeOfDay 23 13 59)) $ pl @(Guard "hh:mm:ss regex failed" (Re HmsRE Id) >> ReadP TimeOfDay Id) "23:13:59"
   , expectPE (FailT "hh:mm:ss regex failed") $ pl @(Guard "hh:mm:ss regex failed" (Re HmsRE Id) >> ReadP TimeOfDay Id) "23:13:60"
-  , expectPE (FailT "Guards:invalid length(5) expected 3") $ pl @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 1 31 Id, Between 1 12 Id, Between 1990 2050 Id]) [31,11,2000,1,2::Int]
-  , expectPE (PresentT [0,0,0,0,0,0,0,1,2,3]) $ pl @(PadL 10 0 Id) [1..3]
-  , expectPE (PresentT (124,["1","2","2"])) $ pl @('Left Id >> (Succ Id &&& (Pred Id >> ShowP Id >> Ones Id))) (Left 123)
-  , expectPE (PresentT [1,2,3,4]) $ pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3,4::Int]
-  , expectPE (FailT "Guards:invalid length(5) expected 4") $ pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3,4,5::Int]
-  , expectPE (FailT "Guards:invalid length(3) expected 4") $ pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (Between 0 255 Id)) [1,2,3::Int]
-  , expectPE (PresentT (readNote @UTCTime "failed to read utc" "1999-01-01 12:12:12 UTC")) $ pl @(ParseTimeP UTCTime "%F %T" Id) "1999-01-01 12:12:12"
-  , expectPE (PresentT 123) $ pl @(JustDef 0 Id) (Just 123)
-  , expectPE (PresentT 0) $ pl @(JustDef 0 Id) Nothing
-  , expectPE (PresentT 12) $ pl @(LastDef 0 Id) [1..12]
-  , expectPE (PresentT 0) $ pl @(LastDef 0 Id) []
+  , expectPE (PresentT (124,["1","2","2"])) $ pl @(Left' >> (Succ Id &&& (Pred Id >> ShowP Id >> Ones Id))) (Left 123)
   , expectPE (PresentT (1,("asdf",True))) $ pl @'(1,'("asdf",'True)) ()
-  , expectPE (PresentT ("abc", True)) $ pl @(TheseId 'True "xyz") (This "abc")
-  , expectPE (PresentT ("xyz", False)) $ pl @(TheseId 'True "xyz") (That False)
-  , expectPE (PresentT ("abc", False)) $ pl @(TheseId 'True "xyz") (These "abc" False)
-  , expectPE (PresentT ("xyz", True)) $ pl @(TheseDef '("xyz",'True) Id) (This "abc")
-  , expectPE (PresentT ("xyz", True)) $ pl @(TheseDef '("xyz",'True) Id) (That False)
-  , expectPE (PresentT ("abc", False)) $ pl @(TheseDef '("xyz",'True) Id) (These "abc" False)
-  , expectPE (PresentT 3) $ pl @(Id !! Char1 "d") (M.fromList $ zip "abcd" [0 ..])
   , expectPE (PresentT (12, False)) $ pl @('These Id (Not Id)) (These 12 True)
-  , expectPE (PresentT (SG.Any True)) $ pl @(Coerce SG.Any) True
-  , expectPE (PresentT True) $ pl @(Coerce Bool) (SG.Any True)
-  , expectPE (PresentT (3, SG.Any True)) $ pl @(Id !! FromString _ "d" &&& (Map (Snd Id >> Gt 3 >> Coerce SG.Any) (IToList _ Id) >> MConcat Id) ) (M.fromList $ zip (map T.singleton "abcdefgh") [0 ..])
-  , expectPE (PresentT (3, True)) $ pl @(Id !! FromString _ "d" &&& (Map (Snd Id >> Gt 3 >> Wrap SG.Any Id) (IToList _ Id) >> MConcat Id >> Unwrap Id) ) (M.fromList $ zip (map T.singleton "abcdefgh") [0 ..])
     --- have to wrap with W cos different kinds
-  , expectPE TrueT $ pl @(Do '[ W ('PresentT I), W 'FalseT, Not Id]) False
-  , expectPE FalseT $ pl @(Do '[ W ('PresentT Id), W 'FalseT ]) True -- have to wrap them cos BoolT a vs BoolT Bool ie different types
   , expectPE TrueT $ pl @('PresentT I >> Not 'FalseT) False
   -- IxL "d" doesnt work cos is Text not String
-  , expectPE (PresentT 3) $ pl @(Id !! FromString _ "d") (M.fromList $ zip (map T.singleton "abcd") [0 ..])
   -- use Fromstring
-  , expectPE (PresentT 3) $ pl @(Id !! FromString _ "d") (M.fromList $ zip (map T.singleton "abcd") [0 ..])
   , expectPE (PresentT [7,9,9,2,7,3,9,8,7,1,3]) $ pl @(Map (ReadP Int Id) (Ones Id) >> Guard "checkdigit fail" (Luhn Id)) "79927398713"
   , expectPE (FailT "checkdigit fail") $ pl @(Map (ReadP Int Id) (Ones Id) >> Guard "checkdigit fail" (Luhn Id)) "79927398714"
   , expectPE (PresentT [10,14,15,9]) $ pl @(MM1 16 >> MM2 16) "aef9"
   , expectPE (FailT "invalid base 16") $ pl @(MM1 16 >> MM2 16) "aef9g"
   , expectPE (FailT "found empty") $ pl @(MM1 16 >> MM2 16) ""
   , expectPE (FailT "0<=x<n") $ pl @(MM2 16) [10,1,17,1,-3,7]
-  , expectPE (PresentT ((10,'c'),True)) $ pl @Unassoc (10,('c',True))
-  , expectPE (PresentT (10,('c',True))) $ pl @Assoc ((10,'c'),True)
-  , expectPE (PresentT ((10,'c'),True)) $ pl @(Assoc >> Unassoc) ((10,'c'),True)
   , expectPE (PresentT 70) $ pl @(Luhn' 11) "79927398713"
   , expectPE (FailT "expected 71 mod 10 = 0 but found 1") $ pl @(Luhn' 11) "79927398714"
 
@@ -458,382 +89,64 @@ -- have to check the length of the match vs input to see that are the same
   , expectPE (PresentT [1,3,4,15]) $ pl @(((Rescan "([[:xdigit:]])" Id >> Map (Snd Id >> OneP Id >> ReadBase Int 16 Id) Id) &&& Id) >> Guard "notallmatched" ((Len *** Len) >> Fst Id == Snd Id) >> Fst Id) "134F"
   , expectPE (FailT "notallmatched") $ pl @(((Rescan "([[:xdigit:]])" Id >> Map (Snd Id >> OneP Id >> ReadBase Int 16 Id) Id) &&& Id) >> Guard "notallmatched" ((Len *** Len) >> Fst Id == Snd Id) >> Fst Id) "134g"
-  , expectPE (PresentT True) $ pl @(FoldMap SG.Any Id) [False,False,True,False]
-  , expectPE (PresentT False) $ pl @(FoldMap SG.All Id) [False,False,True,False]
   , expectPE TrueT $ pl @(Map (ReadP _ Id) (Ones Id) >> Luhn Id) "12345678903"
   , expectPE FalseT $ pl @(Map (ReadP _ Id) (Ones Id) >> Luhn Id) "12345678904"
   , expectPE (FailT "incorrect number of digits found 10 but expected 11 in [1234567890]") $ pl @(Luhn' 11) "1234567890"
-  , expectPE (PresentT ([1,2],[3,4,5,6,7,8])) $ pl @(Break (If (Gt 2) 'True (If (Gt 4) (Failt _ "ASfd") 'False)) Id) [1..8]
-  , expectPE (PresentT ([1,2],[3,4,5,6,7,8])) $ pl @(Break (Case 'False '[Gt 2,Gt 4] '[ W 'True, Failt _ "ASfd"] Id) Id) [1..8]  -- case version
-  , expectPE (FailT "ASfd") $ pl @(Break (If (Gt 2) (Failt _ "ASfd") 'False) Id) [1..8]
-  , expectPE (PresentT ([(1,False),(2,False),(3,False)],[(4,True),(5,True),(6,False)])) $ pl @(Break (Snd Id) Id) (zip [1..] [False,False,False,True,True,False])
-  , expectPE (PresentT ([(1,False),(2,False),(3,False),(4,False)],[])) $ pl @(Break (Snd Id) Id) (zip [1..] [False,False,False,False])
-  , expectPE (PresentT ([],[(1,True),(2,True),(3,True),(4,True)])) $ pl @(Break (Snd Id) Id) (zip [1..] [True,True,True,True])
   , (@?=) (Just "abc") ((_FailT # "abc") ^? _FailT)
   , (@?=) (Just ()) ((_TrueT # ()) ^? _TrueT)
   , (@?=) (Just ()) ((_FalseT # ()) ^? _FalseT)
   , (@?=) (Just 'x') ((_PresentT # 'x') ^? _PresentT)
   , expectPE (PresentT (111,'b')) $ pl @('(123,Char1 "c") >> (Id - 12 *** Pred Id)) ()
-  , expectPE (PresentT (SG.Min 19)) $ pl @((FromInteger _ 12 &&& Id) >> Fst Id + Snd Id) (SG.Min 7)
-  , expectPE (PresentT (SG.Product 84)) $ pl @((FromInteger _ 12 &&& Id) >> SapA) (SG.Product 7)
-  , expectPE (PresentT "xyxyxyxy") $ pl @(STimes (Fst Id) (Snd Id)) (4,['x','y'])
-  , expectPE (PresentT (concat (replicate 16 "abc"))) $ pl @(FoldN 4 Id ((Id &&& Id) >> SapA)) "abc"
-  , expectPE (PresentT (concat (replicate 4 "abc"))) $ pl @(STimes (Fst Id) (Snd Id)) (4,"abc")
-  , expectPE (PresentT (concat (replicate 4 "abc"))) $ pl @(STimes 4 Id) "abc"
-  , expectPE (PresentT "abcd") $ pl @(Map (FromEnum Id) Id >> Map (ToEnum Char Id) Id) ("abcd" :: String)
-  , expectPE (FailT "ToEnum IO e=Prelude.Enum.Ordering.toEnum: bad argument(2)") $ pl @(Map (FromEnum Id) Id >> Map (Id - 97 >> ToEnum Ordering Id) Id) ("abcde" :: String)
-  , expectPE (PresentT ([2,3,5,7,11,13], [1,4,6,8,9,10,12,14,15])) $ pl @(Partition (Prime Id) Id) [1..15]
   , expectPE (FailT "'Nothing found Just") $ pl @'Nothing (Just 12)
-  , expectPE (PresentT (Just 10,((),()))) $ pl @(Id &&& '() &&& ()) (Just 10)
-  , expectPE (PresentT [(-999) % 1,10 % 1,20 % 1,(-999) % 1,30 % 1]) $ pl @(Map (Wrap (MM.First _) Id &&& (Pure Maybe (999 -% 1 ) >> Wrap (MM.First _) Id)) Id >> Map SapA Id >> Map (Just (Unwrap Id)) Id) [Nothing,Just 10,Just 20,Nothing,Just 30]
-  , expectPE (PresentT 12) $ pl @(MaybeIn 99 Id) (Just 12)
-  , expectPE (PresentT 12) $ pl @(JustDef 99 Id) (Just 12)
-  , expectPE (PresentT 99) $ pl @(MaybeIn 99 Id) Nothing
-  , expectPE (PresentT 99) $ pl @(JustDef 99 Id) Nothing
-  , expectPE (PresentT (-99)) $ pl @(MaybeIn (99 -% 1 ) Id) Nothing
-  , expectPE (PresentT (-99)) $ pl @(JustDef (99 -% 1 ) Id) Nothing
-  , expectPE (PresentT [1,2,3,4,12]) $ pl @(ParaN 5 (Guard "0-255" (Between 0 255 Id))) [1,2,3,4,12]
-  , expectPE (FailT "0-255") $ pl @(ParaN 5 (Guard "0-255" (Between 0 255 Id))) [1,2,3,400,12]
-  , expectPE (PresentT ["141","021","003","000"]) $ pl @(ParaN 4 (PrintF "%03d" Id)) [141,21,3,0::Int]
 
   -- need to fill in the types for both even in ghci
-  , expectPE (PresentT (Just (SG.Sum 10))) $ pl @(Coerce2 (SG.Sum Int)) (Just (10 :: Int))
-  , expectPE (PresentT (Just (SG.Sum 0))) $ pl @(MEmpty2 (SG.Sum _)) (Just ())
-  , expectPE (PresentT 13) $ pl @(FoldMap (SG.Sum _) Id) (Just 13)
-  , expectPE (PresentT 55) $ pl @(FoldMap (SG.Sum _) Id) [1..10]
   , expectPE (PresentT [Just 1,Just 2,Just 3,Just 4]) $ pl @Sequence (Just [1..4])
-  , expectPE (PresentT (Just (SG.Sum 20))) $ pl @(Pure2 SG.Sum) (Just 20)
-  , expectPE (PresentT Nothing) $ pl @(Traverse (If (Gt 3) (Pure Maybe Id) (EmptyT Maybe Id)) Id) [1..5]
-  , expectPE (PresentT Nothing) $ pl @(Traverse (MaybeBool (Le 3) Id) Id) [1..5]
-  , expectPE (PresentT (Just [1,2,3,4,5])) $ pl @(Traverse (If (Gt 0) (Pure Maybe Id) (EmptyT Maybe Id)) Id) [1..5]
-  , expectPE (PresentT (Just [1,2,3,4,5])) $ pl @(Traverse (If (Gt 0) (Pure Maybe Id) (MkNothing _)) Id) [1..5]
-  , expectPE (PresentT (Just [1,2,3,4,5])) $ pl @(Traverse (MaybeBool (Id >= 0) Id) Id) [1..5]
-  , expectPE (PresentT Nothing) $ pl @(Traverse (MaybeBool (Id <= 3) Id) Id) [1..5]
 
-  , expectPE (FailT "PrintF (IO e=printf: bad formatting char 's')") $ pl @(PrintF "%-6s" Id) (1234 :: Int)
-  , expectPE (PresentT "0004d2") $ pl @(PrintF "%06x" Id) (1234 :: Int)
-  , expectPE (PresentT (Left 123)) $ pl @(Pure (Either String) Id >> Swap) 123
   , expectPE (PresentT [13,2,1999]) $ pl @(Rescan DdmmyyyyRE Id >> OneP Id >> Map (ReadP Int Id) (Snd Id)) "13-02-1999"
   , expectPE (PresentT [3,2,1999]) $ pl @(Rescan DdmmyyyyRE Id >> OneP Id >> Map (ReadP Int Id) (Snd Id) >> Ddmmyyyyop) "03-02-1999"
   , expectPE (FailT "month 13 is out of range") $ pl @(Rescan DdmmyyyyRE Id >> OneP Id >> Map (ReadP Int Id) (Snd Id) >> Ddmmyyyyop) "12-13-1999"
-  , expectPE (PresentT [[1],[2,3,4],[5,6,7,8],[9,10,11,12]]) $ pl @(SplitAts '[1,3,4] Id) [1..12]
-  , expectPE (PresentT [[1,2,3],[4]]) $ pl @(SplitAts '[3,1,1,1] Id >> Filter (Not Null) Id) [1..4]
-  , expectPE (PresentT 1) $ pl @(Msg (PrintF "digits=%d" Len) (Head Id)) [1..4]
   , expectPE (PresentT 10) $ pl @(Luhn' 4) "1230"
   , expectPE (FailT "expected 14 mod 10 = 0 but found 4") $ pl @(Luhn' 4) "1234"
-  , expectPE (PresentT "lhs = 123 rhs = asdf") $ pl @(PrintT "lhs = %d rhs = %s" Id) (123::Int,"asdf"::String)
-  , expectPE TrueT $ pl @(DirExists ".") ()
-  , expectPE FalseT $ pl @(DirExists "xxy") ()
-  , expectPE FalseT $ pl @(FileExists "xxy") ()
-  , expectPE TrueT $ pl @(IsInfix "ab" Id) "xyzabw"
-  , expectPE FalseT $ pl @(IsInfix "aB" Id) "xyzAbw"
-  , expectPE TrueT $ pl @(IsInfixI "aB" Id) "xyzAbw"
-  , expectPE FalseT $ pl @(IsInfix "ab" Id) "xyzbaw"
-  , expectPE TrueT $ pl @(IsPrefix "xy" Id) "xyzabw"
-  , expectPE FalseT $ pl @(IsPrefix "ab" Id) "xyzbaw"
-  , expectPE TrueT $ pl @(IsSuffix "bw" Id) "xyzabw"
-  , expectPE FalseT $ pl @(IsSuffix "bw" Id) "xyzbaw"
-  , expectPE TrueT $ pl @(IsInfix (Fst Id) (Snd Id)) ("ab","xyzabw")
-  , expectPE (PresentT [1 % 1,(-3) % 2,(-3) % 1]) $ pl @'[1 % 1 ,3 -% 2,3 -% 1 ] ()
   , expectPE (PresentT [4, 7, 8, 9]) $ pl @'[4,7,8,9] ()
   , expectPE (PresentT ["aa","b","","ddd"]) $ pl @'["aa","b","","ddd"] ()
-  , expectPE (PresentT 17) $ pl @(DoN 4 (Id + 4)) 1
-  , expectPE (PresentT 24) $ pl @((Id <> Id) >> Unwrap Id) (SG.Sum 12)
   , expectPE (PresentT "abcdef") $ pl @(Fst Id <> (Snd Id >> Fst Id)) ("abc",("def",12))
-  , expectPE (PresentT (SG.Sum 25)) $ pl @(Wrap _ 13 <> Id) (SG.Sum @Int 12)
   , expectPE (PresentT 23) $ pl @(Fst Id + Last (Snd Id)) (10,[12,13])
-  , expectPE (PresentT (-1,12)) $ pl @(DivMod (9 - Fst Id) (Last (Snd Id))) (10,[12,13])
-  , expectPE (PresentT [True,False,False,True]) $ pl @(Para '[ W 'True, Ge 12, W 'False, Lt 2 ]) [1,2,-99,-999]
-  , expectPE (FailT "Para:invalid length(3) expected 4") $ pl @(Para '[ W 'True, Ge 12, W 'False, Lt 2 ]) [1,2,-99]
-  , expectPE (FailT "Para:invalid length(7) expected 4") $ pl @(Para '[ W 'True, Ge 12, W 'False, Lt 2 ]) [1,2,-99,-999,1,1,2]
-  , expectPE (FailT "guard(1) err 002") $ pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[ W 'True, Ge 12, W 'False, Lt 2 ]) [1,2,-99,-999]
-  , expectPE (FailT "Guards:invalid length(3) expected 4") $ pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[ W 'True, Ge 12, W 'False, Lt 2 ]) [1,2,-99]
-  , expectPE (FailT "Guards:invalid length(7) expected 4") $ pl @(GuardsQuick (PrintT "guard(%d) err %03d" Id) '[ W 'True, Ge 12, W 'True, Lt 2 ]) [1,22,-99,-999,1,1,2]
-  , expectPE TrueT $ pl @(Fst Id /= Snd Id) ("ab","xyzabw")
-  , expectPE FalseT $ pl @(Fst Id == Snd Id) ("ab","xyzabw")
   , expectPE (PresentT 157) $ pl @(Fst Id * (Snd Id >> Fst Id) + (Snd Id >> Snd Id) `Div` 2) (12,(13,3))
-  , expectPE TrueT $ pl @(Fst Id >= Snd Id || Snd Id > 23 || 12 -% 5 <= ToRational (Fst Id)) (12,13)
-  , expectPE (PresentT LT) $ pl @(Fst Id ==! Snd Id) (3,12)
-  , expectPE TrueT $ pl @(Fst Id ==~ Snd Id) ("aBc","AbC")
-  , expectPE (PresentT EQ) $ pl @(Fst Id ===~ Snd Id) ("aBc","AbC")
-  , expectPE FalseT $ pl @(Fst Id == Snd Id) ("aBc","AbC")
-  , expectPE (PresentT GT) $ pl @(Fst Id ==! Snd Id) ("aBc","AbC")
-  , expectPE (PresentT LT) $ pl @(Snd Id ==! Fst Id) ("aBc","AbC")
-  , expectPE TrueT $ pl @(Fst Id ==~ Snd Id && Fst Id == Snd Id) ("Abc","Abc")
-  , expectPE (PresentT (EQ,EQ)) $ pl @(Fst Id ===~ Snd Id &&& Fst Id ==! Snd Id) ("abc","abc")
-  , expectPE (PresentT "ask%dfas%kef00035 hey %") $ pl @(PrintF "ask%%dfas%%kef%05d hey %%" Id) (35 :: Int)
-  , expectPE (PresentT 100) $ pl @(Id !! 2 !! 0) [[1..5],[10..14],[100..110]]
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! 1 !! 7) [[1..5],[10..14],[100..110]]
-  , expectPE (PresentT '2') $ pl @(IxL Id 1 (Char1 "x")) ("123" :: T.Text)
-  , expectPE (PresentT 'x') $ pl @(IxL Id 15 (Char1 "x")) ("123" :: T.Text)
-  , expectPE (FailT "someval int=45") $ pl @(Fail () (PrintF "someval int=%d" Id)) (45 :: Int)
-  , expectPE (FailT "failing with 45") $ pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) ()) 45
-  , expectPE (PresentT 21) $ pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (Id * 7)) 3
-  , expectPE (PresentT ["2","1"]) $ pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (Id * 7 >> ShowP Id >> Ones Id)) 3
-  , expectPE (FailT "failing with 19") $ pl @(If (Gt 4) (Fail (Hole _) (PrintF "failing with %d" Id)) (ShowP (Id * 7) >> Ones Id)) 19
-  , expectPE (PresentT 31) $ pl @(DoN 4 (Id + 7)) 3
-  , expectPE (PresentT 9) $ pl @(DoN 4 9) ()
-  , expectPE (PresentT 3) $ pl @(Do '[1,2,3]) ()
-  , expectPE (PresentT "xy") $ pl @(DoN 4 "xy") 3
-  , expectPE (PresentT ["xy","xy","xy","xy"]) $ pl @(Repeat 4 "xy") 3
   , expectPE (PresentT (Proxy @'["xy","xy","xy","xy"])) $ pl @(Proxy (RepeatT 4 "xy")) 3
-  , expectPE (PresentT (This @_ @() 'x')) $ pl @(MkThis () Id) 'x'
-  , expectPE (PresentT (This @_ @() 'x')) $ pl @(MkThis () (Fst Id)) ('x',True)
-  , expectPE (PresentT (That 'x')) $ pl @(MkThat () Id) 'x'
-  , expectPE (PresentT (These 'x' True)) $ pl @(MkThese Id 'True) 'x'
-  , expectPE (PresentT 123) $ pl @(MaybeIn 123 Id) (Nothing @Int)
-  , expectPE (PresentT 9) $ pl @(MaybeIn 123 Id) (Just 9)
-  , expectPE (PresentT [1,2,3]) $ pl @(Just Id) (Just [1,2,3])
-  , expectPE (FailT "Just(empty)") $ pl @(Just Id) (Nothing @[Int])
   , expectPE (PresentT (66788,26232)) $ pl @(Last Id >> Id * 123 >> Dup >> (Pred Id *** (ShowP Id >> Rescan "(\\d{2})" Id >> Concat (ConcatMap (Snd Id) Id) >> ReadBase Int 16 Id))) [12,13,543::Int]
-  , expectPE (PresentT "d=009 s=ab") $ pl @(PrintT "d=%03d s=%s" Id) (9::Int,"ab"::String)
-  , expectPE (PresentT "d=009 s=ab c=x f=1.54") $ pl @(PrintT "d=%03d s=%s c=%c f=%4.2f" Id) (9::Int,"ab"::String,'x',1.54::Float)
-  , expectPE (FailT "PrintT(IO e=printf: formatting string ended prematurely)") $ pl @(PrintT "d=%03d s=%s" Id) (9::Int, "ab"::String,'x',1.54::Float)
-  , expectPE (PresentT "lhs = 123 rhs = asdf c=120") $ pl @(PrintT "lhs = %d rhs = %s c=%d" Id) (123::Int,"asdf"::String,'x')
-  , expectPE (PresentT (1,('x',(True,())))) $ pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,'x',True)
-  , expectPE (PresentT (1,('x',(True,())))) $ pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,'x',True)
-  , expectPE (PresentT (1,(1.4,("aaa",())))) $ pl @(Fst Id &&& Snd Id &&& Thd Id &&& ()) (1,1.4,"aaa")
-  , expectPE (PresentT "hello d=12 z someval") $ pl @(PrintT "hello d=%d %c %s" '(12, Char1 "z", "someval")) ()
-  , expectPE (PresentT "ipaddress 001.002.003.004") $ pl @(PrintT "ipaddress %03d.%03d.%03d.%03d" '(1,2,3,4)) ()
 
-  , expectPE (PresentT "001.002.003.004") $ pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4::Int]
-  , expectPE (FailT "PrintL(4) arg count=5") $ pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4,5::Int]
-  , expectPE (FailT "PrintL(4) arg count=3") $ pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3::Int]
 
-  , expectPE (PresentT "001.002.003.004") $ pl @(PrintL 4 "%03d.%03d.%03d.%03d" Id) [1,2,3,4::Int]
-  , expectPE (FailT "Pairs no data found") $ pl @Pairs ([] :: [()])
-  , expectPE (FailT "Pairs only one element found") $ pl @Pairs [1]
-  , expectPE (PresentT [(1,2)]) $ pl @Pairs [1,2]
-  , expectPE (PresentT [(1,2),(2,3)]) $ pl @Pairs [1,2,3]
-  , expectPE (PresentT [(1,2),(2,3),(3,4)]) $ pl @Pairs [1,2,3,4]
-  , expectPE (PresentT "1    2 3 004") $ pl @(PrintL 4 "%d %4d %-d %03d" Id) [1..4::Int]
-  , expectPE (PresentT "2019-08-17") $ pl @(FormatTimeP "%Y-%m-%d" Id) (readNote @Day "invalid day" "2019-08-17")
-  , expectPE (PresentT (20,20)) $ pl @(Dup << Fst Id * Snd Id) (4,5)
-  , expectPE (PresentT (20,20)) $ pl @(Fst Id * Snd Id >> Dup) (4,5)
-  , expectPE (PresentT (These "xxx" 4)) $ pl @(Fst Id <$ Snd Id) (4,These "xxx" 'a')
-  , expectPE (PresentT (This 'a')) $ pl @(Fst Id <$ Snd Id) (4,This @_ @String 'a')
-  , expectPE (PresentT (Just 4)) $ pl @(Fst Id <$ Snd Id) (4,Just 'a')
-  , expectPE (PresentT Nothing) $ pl @(Fst Id <$ Snd Id) (4,Nothing @Int)
-  , expectPE (PresentT (Just 4)) $ pl @(Fst Id <* Snd Id) (Just 4,Just 'a')
-  , expectPE (PresentT (Just 'a')) $ pl @(Fst Id *> Snd Id) (Just 4,Just 'a')
   , expectPE (PresentT ('x',('x',"someval"))) $ pl @Duplicate ('x',"someval")
   , expectPE (PresentT "someval") $ pl @Extract ('x',"someval")
-  , expectPE (PresentT (Just "cdef")) $ pl @(Fst Id <|> Snd Id) (Just "cdef",Just "ab")
-  , expectPE (PresentT "cdefab") $ pl @(Fst Id <|> Snd Id) ("cdef","ab"::String)
   , expectPE (PresentT (9,"abc")) $ pl @(I $$ 9 $$ "abc") (,)
   , expectPE (PresentT ("abc",9)) $ pl @(9 $& "abc" $& I) (,)
   , expectPE (PresentT "28") $ pl @(Fst Id $$ Snd Id) (show . (7*),4)
   , expectPE (PresentT (12,"12")) $ pl @(Fst Id $$ Snd Id $$ ShowP (Snd Id)) ((,),12)
---  , expectPE (PresentT (Just (This [1,2,3,4]))) $ pl @(ZipTheseF (Fst Id) (Snd Id)) (Just [1..4],Nothing @())
---  , expectPE (PresentT [These 1 'a',These 2 'b',These 3 'c',This 4]) $ pl @(ZipTheseF (Fst Id) (Snd Id)) ([1..4],['a'..'c'])
-  , expectPE (PresentT [True,True,True,True]) $ pl @('True <$ Id) [1..4]
-  , expectPE (PresentT (Compose (Just "aaaa"))) $ pl @(Char1 "ab" <$ Id) (Compose $ Just [1..4])
   , expectPE (PresentT (4,("aa",'x'))) $ pl @'(4,'(Fst Id,Snd Id)) ("aa",'x')
   , expectPE (PresentT (4,"aa",'x')) $ pl @'(4,Fst Id,Snd Id) ("aa",'x')
-  , expectPE (PresentT (Just [10])) $ pl @(Pure2 []) (Just 10)
-  , expectPE (PresentT "hello") $ pl @Extract (10,"hello")
-  , expectPE (PresentT (M.fromList [(4,"x"),(5,"dd")])) $ pl @(FromList (M.Map _ _)) [(4,"x"),(5,"dd")]
-  , expectPE (PresentT False) $ pl @(FromList (M.Map _ _) >> I !! Char1 "y") [('x',True),('y',False)]
-  , expectPE (PresentT (Just False)) $ pl @(FromList (M.Map _ _) >> Lookup Id (Char1 "y")) [('x',True),('y',False)]
-  , expectPE (PresentT Nothing) $ pl @(FromList (M.Map _ _) >> Lookup Id (Char1 "z")) [('x',True),('y',False)]
-  , expectPE (FailT "(!!) index not found") $ pl @(FromList (M.Map _ _) >> Id !! Char1 "z") [('x',True),('y',False)]
-  , expectPE (PresentT ["abc","bcd","cde","def","efg","fgh","ghi","hi","i"]) $ pl @(Unfoldr (If Null (MkNothing _) ('(Take 3 Id, Drop 1 Id) >> MkJust Id)) Id) "abcdefghi"
-  , expectPE (PresentT [[1,2],[3,4],[5]]) $ pl @(Unfoldr (If Null (MkNothing _) (Pure _ (SplitAt 2 Id))) Id) [1..5]
-  , expectPE (PresentT [[1,2],[3,4],[5]]) $ pl @(Unfoldr (MaybeBool (Not Null) (SplitAt 2 Id)) Id) [1..5]
-  , expectPE (PresentT [99,1,2,3,4,5]) $ pl @(FlipT (:+) (Fst Id) (Snd Id)) ([1..5],99)
-  , expectPE (PresentT [99,1,2,3,4,5]) $ pl @(Fst Id :+ Snd Id) (99,[1..5])
-  , expectPE (PresentT [[99],[1,99],[2,1,99],[3,2,1,99],[4,3,2,1,99],[5,4,3,2,1,99]]) $ pl @(Scanl (Snd Id :+ Fst Id) (Fst Id) (Snd Id)) ([99],[1..5])
-  , expectPE (PresentT [[99]]) $ pl @(Scanl (Snd Id :+ Fst Id) (Fst Id) (Snd Id)) ([99],[])
-  , expectPE (FailT "yy") $ pl @(Unfoldr (If Null (MkNothing _) (Guard "yy" (Len < 3) >> Pure _ (SplitAt 2 Id))) Id) [1..5]
-  , expectPE (FailT "yy") $ pl @(Unfoldr (MaybeBool (Not Null) (Guard "yy" (Len < 3) >> SplitAt 2 Id)) Id) [1..5]
-  , expectPE (PresentT [4,1,2,3]) $ pl @(4 :+ '[1,2,3]) ()
-  , expectPE (PresentT [1,2,3,4]) $ pl @('[1,2,3] +: 4) ()
-  , expectPE (PresentT [4,1,2,3]) $ pl @(Fst Id :+ Snd Id) (4,[1,2,3])
-  , expectPE (PresentT [1,2,3,4]) $ pl @(Snd Id +: Fst Id) (4,[1,2,3])
-  , expectPE (PresentT "abcx") $ pl @("abc" +: Char1 "x") ()
-  , expectPE (PresentT "abcx") $ pl @(Fst Id +: Snd Id) ("abc" :: T.Text,'x')
-  , expectPE (PresentT [5,1,2,3]) $ pl @(FlipT (:+) '[1,2,3] 5) ()
   , expectPE (PresentT (map ModifiedJulianDay [0,1,2,3,4,5])) $ pl @(EnumFromTo (Fst Id) (Snd Id)) (ModifiedJulianDay 0, ModifiedJulianDay 5)
-  , expectPE (PresentT (map ModifiedJulianDay [0,1,2,3,4,5])) $ pl @((ToEnum Day Id *** ToEnum Day Id) >> EnumFromTo (Fst Id) (Snd Id)) (0,5)
-  , expectPE (FailT "xx") $ pl @(Unfoldr (Guard "xx" (Len > 4) >> Uncons) Id) [1..10]
-  , expectPE (PresentT [1,2,3,4,5,6,7,8,9,10]) $ pl @(Unfoldr Uncons Id) [1..10]
-  , expectPE (PresentT [99,98,97,96]) $ pl @(IterateN 4 (Pred Id)) 99
   , expectPE (PresentT (4,'x')) $ pl @('(,) 4 %% Char1 "x") ()
-  , expectPE (PresentT (Just False)) $ pl @(FromList (M.Map _ _) >> Lookup Id %% Char1 "y") [('x',True),('y',False)]
   , expectPE (PresentT (4,"abc")) $ pl @('(,) %% 4 %% "abc") ()
   , expectPE (PresentT ("abc",4)) $ pl @(4 %& "abc" %& '(,)) ()
   , expectPE (PresentT ("abc",4)) $ pl @(FlipT '(,) 4 "abc") ()
-  , expectPE (PresentT (1,[])) $ pl @(Uncons >> MaybeIn '(1,MEmptyT _) Id) []
   , expectPE (PresentT []) $ pl @'[] 4
-  , expectPE (PresentT (SG.Sum 3)) $ pl @(FromInteger (SG.Sum _) (Fst Id)) (3,"A")
-  , expectPE (PresentT (123 :: DiffTime)) $ pl @(FromInteger DiffTime 123) 'x'
-  , expectPE (PresentT (0.8 :: Float)) $ pl @(FromRational Float (4 % 5)) ()
-  , expectPE (PresentT (14 % 1)) $ pl @(ToRational 14) ()
-  , expectPE (PresentT ('y',3)) $ pl @(Id !! 1) [('x',14),('y',3),('z',5)]
-  , expectPE (PresentT (Just ('y',3))) $ pl @(Lookup Id 1) [('x',14),('y',3),('z',5)]
-  , expectPE (PresentT Nothing) $ pl @(Lookup Id 14) [('x',14),('y',3),('z',5)]
-  , expectPE (FailT "(!!) index not found") $ pl @(Id !! 14) [('x',14),('y',3),('z',5)]
-  , expectPE (PresentT 99) $ pl @(Fst Id) (99,'a',False,1.3)
-  , expectPE (PresentT 'a') $ pl @(Snd Id) (99,'a',False,1.3)
-  , expectPE (PresentT False) $ pl @(Thd Id) (99,'a',False,1.3)
-  , expectPE (PresentT "someval") $ pl @(L4 Id) (99,'a',False,"someval")
-  , expectPE (PresentT [1,-5,5,-1]) $ pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Floor _ Id) Id) ()
-  , expectPE (PresentT [1,-4,6,-1]) $ pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Ceiling _ Id) Id) ()
-  , expectPE (PresentT [1,-4,5,-1]) $ pl @('[1 % 1 ,Negate (33 % 7), 21 % 4,Signum (7 -% 5)] >> Map (Truncate _ Id) Id) ()
-  , expectPE (PresentT @Integer 2) $ pl @(Truncate' (Fst Id >> Unproxy ) (Snd Id)) (Proxy @Integer,2.3)
-  , expectPE (PresentT @Int 2) $ pl @(Truncate' (Fst Id) (Snd Id)) (1::Int,2.3)
-  , expectPE (PresentT @Float 0.4) $ pl @(FromRational' (Fst Id) (Snd Id)) (1::Float,2 % 5)
-  , expectPE (PresentT (5 % 3)) $ pl @(ToRational 5 / ToRational 3) 'x'
-  , expectPE (PresentT (-5 % 3)) $ pl @(5 % 1 / 3 -% 1 ) 'x'
-  , expectPE (PresentT (-5 % 3)) $ pl @(5 -% 1 / Fst Id) (3,'x')
   , expectPE (PresentT (-5 % 3)) $ pl @(Snd Id / Fst Id) (-3,5)
   , expectPE (FailT "(/) zero denominator") $ pl @(Snd Id / Fst Id) (0,5)
-  , expectPE (PresentT 16) $ pl @(FoldL (Guard "someval" (Fst Id < Snd Id) >> Snd Id) (Head Id) (Tail Id)) [1,4,7,9,16]
-  , expectPE (FailT "7 not less than 6") $ pl @(FoldL (Guard (PrintT "%d not less than %d" Id) (Fst Id < Snd Id) >> Snd Id) (Head Id) (Tail Id)) [1,4,7,6,16::Int]
-  , expectPE (PresentT (True,16)) $ pl @(FoldL (If ((Fst Id >> Fst Id) && (Snd Id > Snd (Fst Id))) '( 'True, Snd Id ) '( 'False, Snd (Fst Id) )) '( 'True, Head Id ) (Tail Id)) [1,4,7,9,16]
-  , expectPE (PresentT (False,16)) $ pl @(FoldL (If ((Fst Id >> Fst Id) && (Snd Id > Snd (Fst Id))) '( 'True, Snd Id ) '( 'False, Snd (Fst Id) )) '( 'True, Head Id ) (Tail Id)) [1,4,7,9,16,2]
   , expectPE (PresentT (False,7))
-     $ pl @(FoldL (If (Fst (Fst Id))
+     $ pl @(Foldl (If (Fst (Fst Id))
                     (If (Snd Id > Snd (Fst Id))
                        '( 'True, Snd Id )
                        '( 'False, Snd (Fst Id) )
                     ) (Fst Id))
                    '( 'True, Head Id) (Tail Id)) [1,4,7,6,16]
-  , expectPE (PresentT [1,2,3,4]) $ pl @(Init Id) [1..5]
-  , expectPE (FailT "Init(empty)") $ pl @(Init Id) ([] :: [()])
-  , expectPE (PresentT [2,3,4,5]) $ pl @(Tail Id) [1..5]
-  , expectPE (FailT "Tail(empty)") $ pl @(Tail Id) ([] :: [()])
   , expectPE (PresentT [10,12,13]) $ pl @(CatMaybes Id) [Just 10, Just 12, Nothing, Just 13]
-  , expectPE (PresentT [5,4,3,2,1]) $ pl @(FoldL (Snd Id :+ Fst Id) (MEmptyT [_]) Id) [1..5]
-  , expectPE (PresentT (map SG.Min [9,10,11,12,13])) $ pl @(EnumFromTo (Pure SG.Min 9) (Pure _ 13)) ()
-  , expectPE (PresentT (map SG.Min [9,10,11,12,13])) $ pl @(EnumFromTo (Wrap (SG.Min _) 9) (Wrap _ 13)) ()
---  , expectPE (PresentT (Just 'x')) $ pl @(Purex (Fst Id) (Snd Id)) (Just 10,'x')
-  , expectPE (PresentT (Just 'x')) $ pl @(Snd Id <$ Fst Id) (Just 10,'x')
-  , expectPE (PresentT (Nothing @(SG.Sum _))) $ pl @(MEmptyT' Id) (Just (SG.Sum 12))
-  , expectPE (PresentT ([4,99],"xy")) $ pl @PartitionEithers [Left 4, Right 'x', Right 'y',Left 99]
-  , expectPE (PresentT ([4,99],"xy",[(3,'b'),(5,'x')])) $ pl @PartitionThese [This 4, That 'x', That 'y',These 3 'b', This 99, These 5 'x']
-  , expectPE (PresentT [1,2,3]) $ pl @(MapMaybe (MaybeBool (Le 3) Id) Id) [1..5]
-  , expectPE (PresentT [4,5]) $ pl @(MapMaybe (MaybeBool (Gt 3) Id) Id) [1..5]
-  , expectPE (PresentT [94,93,92,91]) $ pl @(IterateWhile (Id > 90) (Pred Id)) 94
-  , expectPE (PresentT [94,93,92,91,90]) $ pl @(IterateUntil (Id < 90) (Pred Id)) 94
-  , expectPE (PresentT [95,94,93,92,91]) $ pl @(IterateNWhile 10 (Id > 90) (Pred Id)) 95
-  , expectPE (PresentT [95,94,93]) $ pl @(IterateNWhile 3 (Id > 90) (Pred Id)) 95
-  , expectPE (PresentT [95,94,93,92,91]) $ pl @(IterateNUntil 10 (Id <= 90) (Pred Id)) 95
-  , expectPE (PresentT [95,94,93]) $ pl @(IterateNUntil 3 (Id <= 90) (Pred Id)) 95
-  -- check for infinite loops
-  , expectPE (FailT "Unfoldr (9999,1):recursion limit i=100") $ pl @(IterateNUntil 9999 'False I) 1
-  , expectPE (FailT "Scanl list size exceeded") $ pl @(FoldL (Fst Id) '() (EnumFromTo 1 9999)) ()
-  , expectPE (PresentT "a=9 b=rhs") $ pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (These @Int 9 "rhs")
-  , expectPE (PresentT "a=10") $ pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (This @Int 9)
-  , expectPE (PresentT "b=rhs") $ pl @(TheseX (PrintF "a=%d" (Succ (Snd Id))) ("b=" <> Snd Id) (PrintT "a=%d b=%s" (Snd Id)) Id) (That @Int "rhs")
-  , expectPE (PresentT ([] :: [Int])) $ pl @(HeadDef (MEmptyT _) Id) (map (:[]) ([] :: [Int]))
-  , expectPE (PresentT ([10] :: [Int])) $ pl @(HeadDef (MEmptyT _) Id) (map (:[]) ([10..14] :: [Int]))
-  , expectPE (PresentT 10) $ pl @(HeadDef (Fst Id) (Snd Id)) (99,[10..14])
-  , expectPE (PresentT 99) $ pl @(HeadDef (Fst Id) (Snd Id)) (99,[] :: [Int])
-  , expectPE (PresentT 43) $ pl @(HeadDef 43 (Snd Id)) (99,[] :: [Int])
-  , expectPE (PresentT (Just 'd')) $ pl @(Lookup "abcdef" 3) ()
-  , expectPE (PresentT (Just 5)) $ pl @(Lookup '[1,2,3,4,5,6] 4) ()
-  , expectPE (PresentT 5) $ pl @(LookupDef '[1,2,3,4,5,6] 4 Id) 23
-  , expectPE (PresentT 5) $ pl @(LookupDef '[1,2,3,4,5,6] 4 (Fst Id)) (23,'x')
-  , expectPE (PresentT 23) $ pl @(LookupDef '[1,2,3,4,5,6] 99 Id) 23
-  , expectPE (PresentT 23) $ pl @(LookupDef '[1,2,3,4,5,6] 99 (Fst Id)) (23,'x')
-  , expectPE (PresentT 5) $ pl @(LookupDef '[1,2,3,4,5,6] 4 999) (23,'x')
-  , expectPE (PresentT 999) $ pl @(LookupDef '[1,2,3,4,5,6] 40 999) (23,'x')
-  , expectPE (PresentT (SG.Min 5)) $ pl @(LookupDef (Fst Id) 4 (MEmptyT _)) (map SG.Min [1::Int .. 10],'x')
-  , expectPE (PresentT (mempty @(SG.Min _))) $ pl @(LookupDef (Fst Id) 999 (MEmptyT _)) (map SG.Min [1::Int .. 10],'x')
-  , expectPE (FailT "someval") $ pl @(LookupFail "someval" (Fst Id) 999) (map SG.Min [1::Int .. 10],'x')
-  , expectPE (FailT "abcsomeval") $ pl @(Fail (Snd Id >> Unproxy) (Fst Id <> "someval")) ("abc",Proxy @Int)
-  , expectPE (FailT "char=x") $ pl @(LookupFail (PrintF "char=%c" (Snd Id)) (Fst Id) 49) (map SG.Min [1::Int ..10],'x')
-  , expectPE (FailT "someval=13") $ pl @(LeftFail (PrintF "someval=%d" (Fst (Snd Id))) (Snd Id)) (13::Int,Right @(SG.Sum Int) "abc")
-  , expectPE (FailT "someval=abc") $ pl @(LeftFail (PrintF "someval=%s" (Fst Id)) Id) (Right @(SG.Sum Int) ("abc" :: String))
-  , expectPE (FailT "msg=Abc def") $ pl @(HeadFail (PrintF "msg=%s def" (Fst Id)) (Snd Id)) ("Abc" :: String,[]::[Int])
-  , expectPE (PresentT 'c') $ pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) (['a'..'e'],2)
-  , expectPE (PresentT 'x') $ pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) (['a'..'e'],999)
-  , expectPE (PresentT 'x') $ pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") Id) ([],2)
-  , expectPE (PresentT 'x') $ pl @(LookupDef' (Fst Id) (Snd Id) (Char1 "xx") (Snd Id)) ('w',([],2))
-  , expectPE (PresentT 'c') $ pl @(LookupDef' (Fst Id) (Snd Id) (Fst Id) (Snd Id)) ('x',(['a'..'e'],2))
-  , expectPE (PresentT(SG.Min 13)) $ pl @(LookupDef' (Fst Id) (Snd Id) (MEmptyT _) (Snd Id)) ('x',(map SG.Min [10..15::Int], 3))
 
-  , expectPE (PresentT 9) $ pl @(HeadDef 9 (Fst Id)) ([],True)
-  , expectPE (PresentT 1) $ pl @(HeadDef 9 (Fst Id)) ([1..5],True)
-  , expectPE (PresentT 10) $ pl @(HeadDef 3 (Fst Id)) ([10..15],True)
 
-  , expectPE (PresentT 9) $ pl @(LastDef 9 (Fst Id)) ([],True)
-  , expectPE (PresentT 5) $ pl @(LastDef 9 (Fst Id)) ([1..5],True)
-  , expectPE (PresentT 15) $ pl @(LastDef 3 (Fst Id)) ([10..15],True)
+  , expectPE (FailT "abcsomeval") $ pl @(Fail (Snd Id >> Unproxy) (Fst Id <> "someval")) ("abc",Proxy @Int)
 
-  , expectPE (PresentT [9,7]) $ pl @(InitDef '[9,7] (Fst Id)) ([],True)
-  , expectPE (PresentT [1,2,3,4]) $ pl @(InitDef '[9,7] (Fst Id)) ([1..5],True)
-  , expectPE (PresentT [10,11,12,13,14]) $ pl @(InitDef '[3] (Fst Id)) ([10..15],True)
 
-  , expectPE (PresentT [9,7]) $ pl @(TailDef '[9,7] (Fst Id)) ([],True)
-  , expectPE (PresentT [2,3,4,5]) $ pl @(TailDef '[9,7] (Fst Id)) ([1..5],True)
-  , expectPE (PresentT [11,12,13,14,15]) $ pl @(TailDef '[3] (Fst Id)) ([10..15],True)
-
-  , expectPE (FailT "a=4 b=someval") $ pl @(TailFail (PrintT "a=%d b=%s" (Snd Id)) (Fst Id)) ([]::[()],(4::Int,"someval" :: String))
-
-  , expectPE (PresentT (Just 1)) $ pl @FMapFst (Just (1,'x'))
-  , expectPE (PresentT (Just 'x')) $ pl @FMapSnd (Just (1,'x'))
-  , expectPE (PresentT (Nothing @Int)) $ pl @FMapSnd (Nothing @(Char,Int))
-  , expectPE (PresentT [1,2,3]) $ pl @FMapFst [(1,'x'), (2,'y'), (3,'z')]
-  , expectPE (PresentT (Right 'x')) $ pl @FMapSnd (Right @() (1,'x'))
-  , expectPE (PresentT (Left @_ @Double "x")) $ pl @FMapSnd (Left @_ @(Int,Double) "x")
-
-  , expectPE (PresentT [1,10,99]) $ pl @Thiss [This 1, This 10,That 'x', This 99, That 'y']
-  , expectPE (PresentT "xy") $ pl @Thats [This 1, This 10,That 'x', This 99, That 'y']
-  , expectPE (PresentT ("xabz",[1,10])) $ pl @PartitionEithers [Left 'x', Right 1,Left 'a', Left 'b',Left 'z', Right 10]
-  -- need Either a b to be fully typed unfortunately
-  , expectPE (FailT "found rhs=10") $ pl @(LeftFail (PrintF "found rhs=%d" (Fst Id)) Id) (Right @String @Int 10)
-  , expectPE (FailT "found rhs=23") $ pl @(LeftFail (PrintF "found rhs=%d" (Snd Id >> Snd Id >> Snd Id)) (Snd Id >> Fst Id)) ('x',(Right @() 10,23::Int))
-  , expectPE (PresentT "abc") $ pl @(LeftFail (PrintF "found rhs=%d" (Snd (Snd (Snd Id)))) (Fst (Snd Id))) ('x',(Left @_ @() "abc",23::Int))
-  , expectPE (PresentT ([1,4,10],"xy",[(9,'z'),(8,'y')])) $ pl @PartitionThese [This 1,That 'x',This 4,That 'y',These 9 'z',This 10,These 8 'y']
-  , expectPE (PresentT [('a',1),('a',10),('z',14),('m',22)]) $ pl @(SortOn (Snd Id) (Snd Id)) ((),[('z',14),('a',10),('m',22),('a',1)])
-  , expectPE (PresentT [('z',1),('m',22),('a',10)]) $ pl @(SortOnDesc (Fst Id) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
-  , expectPE (PresentT [('a',10),('m',22),('z',1)]) $ pl @(SortOn (Fst Id) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
-  , expectPE (PresentT [('z',1),('m',22),('a',10)]) $ pl @(SortBy (Swap >> OrdA (Fst Id)) (Snd Id)) ((),[('z',1),('a',10),('m',22)])
-  , expectPE (PresentT ["aa","cx","by","az"]) $ pl @(SortBy (OrdA Reverse) Id) ["az","by","cx","aa"]
-  , expectPE (PresentT [('a',10),('a',9),('m',22),('m',10),('z',1)]) $ pl @(SortOn (Fst Id) Id) [('z',1),('a',10),('m',22),('a',9),('m',10)]
-  , expectPE (PresentT [('a',9),('a',10),('m',10),('m',22),('z',1)]) $ pl @(SortOn Id Id) [('z',1),('a',10),('m',22),('a',9),('m',10)]
-  , expectPE (PresentT (False,9)) $ pl @(Just Uncons >> FoldL (If (Fst (Fst Id)) (If (Snd (Fst Id) < Snd Id) '( 'True,Snd Id) '( 'False, Snd Id)) (Fst Id)) '( 'True,Fst Id) (Snd Id)) [-10,-2,2,3,4,10,9,11]
-  , expectPE (PresentT (True,11)) $ pl @(Just Uncons >> FoldL (If (Fst (Fst Id)) (If (Snd (Fst Id) < Snd Id) '( 'True,Snd Id) '( 'False, Snd Id)) (Fst Id)) '( 'True,Fst Id) (Snd Id)) [-10,2,3,4,10,11]
-  , expectPE (FailT "pivot=5 value=3(2)") $ pl @(SortBy (If (Fst Id==5 && Snd Id==3) (Failt _ (PrintT "pivot=%d value=%d" Id)) 'GT) (Snd Id)) ((), [5,7,3,1,6,2,1,3])
-  , expectPE (PresentT [1,1,2,3,3,5,6,7]) $ pl @(SortBy (If (Fst Id==50 && Snd Id==3) (Failt _ (PrintT "pivot=%d value=%d" Id)) (OrdA Id)) (Snd Id)) ((), [5,7,3,1,6,2,1,3])
-  , expectPE TrueT $ pl @(Between (Fst Id >> Fst Id) (Fst Id >> Snd Id) (Snd Id)) ((1,4),3)
-  , expectPE FalseT $ pl @(Between (Fst Id >> Fst Id) (Fst Id >> Snd Id) (Snd Id)) ((1,4),10)
-  , expectPE (FailT "no match on (03/29/0x7)") $ pl @(Map (ParseTimes Day '["%Y-%m-%d", "%m/%d/%y", "%b %d %Y"] Id) Id) ["2001-01-01", "Jan 24 2009", "03/29/0x7"]
-  , expectPE (PresentT [readNote @Day "invalid day" "2001-01-01", readNote @Day "invalid day" "2009-01-24", readNote @Day "invalid day" "2007-03-29"]) $ pl @(Map (ParseTimes Day '["%Y-%m-%d", "%m/%d/%y", "%b %d %Y"] Id) Id) ["2001-01-01", "Jan 24 2009", "03/29/07"]
-
-  , expectPE (PresentT "gt3") $ pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 15
-  , expectPE (PresentT "lt2") $ pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 1
-  , expectPE (PresentT "eq3") $ pl @(Case (Snd Id >> Failp "xx") '[Gt 3, Lt 2, Same 3] '["gt3","lt2","eq3"] Id) 3
-
-  , expectPE (FailT "no match") $ pl @(Case (Snd Id >> Failp "no match") '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (FailT "no match for 015") $ pl @(Case (Fail (Snd Id >> Unproxy) (PrintF "no match for %03d" (Fst Id))) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (FailT "no match for 015") $ pl @(Case'' (PrintF "no match for %03d" Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (FailT "no match for 015") $ pl @(Case'' (PrintF "no match for %03d" Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (PresentT "other") $ pl @(Case "other" '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (PresentT "151515") $ pl @(Case (ShowP (Fst Id) >> Id <> Id <> Id) '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (FailT "Case:no match") $ pl @(Case' '[Same 1, Same 2, Same 3] '["eq1","eq2","eq3"] Id) 15
-  , expectPE (FailT "no match for -012") $ pl @(Case'' (PrintF "no match for %04d" Id) '[Between 0 5 Id, Same 6, Between 7 10 Id] '[ 'LT, 'EQ, 'GT] Id) (-12)
   , expectPE (PresentT [Left 1,Left 2,Right "fizz",Left 4,Right "buzz",Right "fizz",Left 7,Left 8,Right "fizz",Right "buzz",Left 11,Right "fizz",Left 13,Left 14,Right "fizzbuzz"]) $ pl @(Map Fizzbuzz''' Id) [1..15]
-  , expectPE (PresentT (Left 'x')) $ pl @(EitherBool (Fst Id > 10) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (7,('x',99))
-  , expectPE (PresentT (Right 99)) $ pl @(EitherBool (Fst Id > 10) (Snd Id >> Fst Id) (Snd Id >> Snd Id)) (11,('x',99))
-  , expectPE (PresentT (Right 99)) $ pl @(EitherBool (Gt 10) "found left" 99) 12
-  , expectPE (PresentT (Left "found left")) $ pl @(EitherBool (Gt 10) "found left" 99) 7
 
-  , expectPE (FailT "msg=someval caught(044)") $ pl @(Catch' (Failt Int "someval") (PrintT "msg=%s caught(%03d)" Id)) (44 :: Int)
-  , expectPE (FailT "msg=OneP 3 elements caught([10,12,13])") $ pl @(Catch' (OneP Id) (Second (ShowP Id) >> PrintT "msg=%s caught(%s)" Id)) [10,12,13]
-  , expectPE (PresentT 10) $ pl @(Catch' (OneP Id) (PrintT "msg=%s caught(%s)" (Second (ShowP Id)))) [10]
-  , expectPE (FailT "msg=OneP 2 elements err s=[10,11]") $ pl @(Catch' (OneP Id) (PrintT "msg=%s err s=%s" (Second (ShowP Id)))) [10,11]
-  , expectPE (PresentT 99) $ pl @(Catch (OneP Id) 99) [10,11]
-  , expectPE (PresentT 10) $ pl @(Catch (OneP Id) 99) [10]
-  , expectPE (PresentT False) $ pl @(Catch (OneP Id) 'True) [False]  -- cant know that this is FalseT cos is driven by type of the list not the 'True part
-  , expectPE FalseT $ pl @(Catch (OneP Id) 'False) [True,True,False]
-  , expectPE TrueT $ pl @(Catch (OneP Id) 'True) []
-  , expectPE (PresentT (-255)) $ pl @(ReadBase Int 16 Id) "-ff"
-  , expectPE (PresentT 255) $ pl @(ReadBase Int 16 Id) "ff"
-  , expectPE (PresentT "-7b") $ pl @(ShowBase 16 Id) (-123)
-  , expectPE (PresentT "7b") $ pl @(ShowBase 16 Id) 123
   , expectPE (PresentT "abc") $ pl @(Thd (Snd (Fst Id))) (('x',(13,False,"abc")),True,'y')
   , expectPE (PresentT 9.3) $ pl @(Fst (Snd (Thd Id))) ('x',True,(13,(9.3,False),"def"))
   , expectPE (PresentT (4,"helo|oleh")) $ pl @'(Len, Id <> "|" <> Reverse) "helo"
@@ -842,7 +155,6 @@   , expectPE (PresentT [1,2,3,1000,998]) $ pl @'[W 1, W 2, W 3, Succ Id, Pred Id] 999
   , expectPE (PresentT [3996,998]) $ pl @'[Id * 4, Pred Id] 999
 
-  , expectPE (PresentT (These [1,2,3,4] "Abcdef")) $ pz @(MkThat _ "Abc" <> MkThis _ '[1,2] <> MkThese [3,4] "def") ()
 
   -- test semigroup interaction
   , expectEQR (These (PresentT 6) (FailT "xyzhello")) $ fmap This (pz @Predicate.Sum [1,2,3]) <> fmap That (pz @(FailS "xyz") 5) <> fmap That (pz @(FailS "hello") 1)
@@ -887,5 +199,3 @@ -- checks that each digit is between 0 and n-1
 type MM1 (n :: Nat) = Map (ReadBase Int n Id) (Ones Id)
 type MM2 (n :: Nat) = ExitWhen "found empty" IsEmpty >> Guard "0<=x<n" (All (Ge 0 && Lt n) Id)
-
-
test/TestRefined2.hs view
@@ -103,10 +103,10 @@                   $ eval2 @OA @Id @(Gt (7 -% 3)) 4.123
 
   , expect2 (Right $ unsafeRefined2 [1,2,3,4] "1.2.3.4")
-                  $ eval2 @OA @(Map (ReadP Int Id) (Resplit "\\." Id)) @(All (Between 0 255 Id) Id && (Len == 4))                   "1.2.3.4"
+                  $ eval2 @OA @(Map (ReadP Int Id) (Resplit "\\." Id)) @(All (Between 0 255 Id) Id && (Len == 4)) "1.2.3.4"
 
-  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds:All(8) i=4 (1048319 <= 65535))")
-                  $ eval2 @OA @Ip6ip @Ip6op "123:Ffeff:1123:11:1"
+  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds: All(8) i=4 (1048319 <= 65535))")
+                  $ eval2 @OAN @Ip6ip @Ip6op "123:Ffeff:1123:11:1"
 
   , expect2 (Right $ unsafeRefined2 [12,2,0,255] "12.2.0.255")
                   $ eval2 @OA @Ip4ip @Ip4op' "12.2.0.255"
@@ -128,12 +128,12 @@                   @(GuardsQuick (PrintT "guard(%d) %d is out of range" Id) '[Between 0 999 Id, Between 0 99 Id, Between 0 9999 Id] >> 'True)
                   "123-45-6789"
 
-  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds:All(8) i=4 (1048319 <= 65535))")
-                  $ eval2 @OA @Ip6ip @Ip6op
+  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds: All(8) i=4 (1048319 <= 65535))")
+                  $ eval2 @OAN @Ip6ip @Ip6op
                   "123:Ffeff:1123:11:1"
 
-  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds:All(8) i=4 (1048319 <= 65535))")
-                  $ eval2 @OA @Ip6ip @Ip6op
+  , expect2 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds: All(8) i=4 (1048319 <= 65535))")
+                  $ eval2 @OAN @Ip6ip @Ip6op
                   "123:Ffeff:1123:11:1"
 
   , expect2 (Right $ unsafeRefined2 [0,0,0,291,65535,4387,17,1] "123:Ffff:1123:11:1")
@@ -337,6 +337,6 @@ 
 test2d :: Either String (Refined2 OU
     TimeUtc
-    (ToDay Id > Just (MkDay '(2020,05,31)))
+    (ToDay Id > 'Just (MkDay '(2020,05,31)))
     ())
 test2d = newRefined2P Proxy ()
test/TestRefined3.hs view
@@ -113,7 +113,7 @@                   $ eval3 @OAN @(Map (ReadP Int Id) (Resplit "\\." Id)) @(All (Between 0 255 Id) Id && (Len == 4)) @""
                   "1.2.3.4"
 
-  , expect3 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds:All(8) i=4 (1048319 <= 65535))")
+  , expect3 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds: All(8) i=4 (1048319 <= 65535))")
                   $ eval3 @OAN @Ip6ip @Ip6op @"" "123:Ffeff:1123:11:1"
 
   , expect3 (Right $ unsafeRefined3 [12,2,0,255] "abc")
@@ -138,7 +138,7 @@                   @"xyz"
                   "123-45-6789"
 
-  , expect3 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds:All(8) i=4 (1048319 <= 65535))")
+  , expect3 (Left $ XTFalse [0,0,0,291,1048319,4387,17,1] "True && False | (out of bounds: All(8) i=4 (1048319 <= 65535))")
                   $ eval3 @OAN @Ip6ip @Ip6op @"xyz"
                   "123:Ffeff:1123:11:1"
 
@@ -201,8 +201,8 @@ 
 yy1, yy2, yy3, yy4 :: RefinedT Identity (MakeR3 Tst1)
 
-yy1 = newRefined3TP @Identity (Proxy @Tst1) "4"
-yy2 = newRefined3TP @Identity (Proxy @Tst1) "3"
+yy1 = newRefined3TP (Proxy @Tst1) "4"
+yy2 = newRefined3TP (Proxy @Tst1) "3"
 
 yy3 = rapply3 (*) yy1 yy2 -- fails
 yy4 = rapply3 (+) yy1 yy2 -- pure ()