packages feed

rerefined 0.2.0 → 0.3.0

raw patch · 29 files changed

+640/−331 lines, 29 filesdep +textdep +text-builder-lineardep +type-level-showdep −typeablydep ~basedep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependencies added: text, text-builder-linear, type-level-show

Dependencies removed: typeably

Dependency ranges changed: base, template-haskell

API changes (from Hackage documentation)

- Rerefined.Predicate: instance Data.Typeable.Internal.Typeable a => Rerefined.Predicate.Predicate (Data.Typeable.Typeably.Typeably a)
- Rerefined.Predicate: instance GHC.Show.Show a => GHC.Show.Show (Rerefined.Predicate.RefineFailure a)
- Rerefined.Predicate.Common: Typeably :: a -> Typeably a
- Rerefined.Predicate.Common: class () => Typeable (a :: k)
- Rerefined.Predicate.Common: newtype () => Typeably a
- Rerefined.Predicate.Common: predicateName1 :: forall p. Predicate p => String -> Int -> ShowS
- Rerefined.Predicate.Common: predicateName2 :: forall l r. (Predicate l, Predicate r) => String -> Int -> ShowS
- Rerefined.Predicate.Logical: And :: LogicOp
- Rerefined.Predicate.Logical: Nand :: LogicOp
- Rerefined.Predicate.Logical: Nor :: LogicOp
- Rerefined.Predicate.Logical: Or :: LogicOp
- Rerefined.Predicate.Logical: Xnor :: LogicOp
- Rerefined.Predicate.Logical: Xor :: LogicOp
- Rerefined.Predicate.Logical: class ReifyLogicOp (op :: LogicOp)
- Rerefined.Predicate.Logical: data LogicOp
- Rerefined.Predicate.Logical: data Logical (op :: LogicOp) l r
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.And
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.Nand
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.Nor
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.Or
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.Xnor
- Rerefined.Predicate.Logical: instance Rerefined.Predicate.Logical.ReifyLogicOp 'Rerefined.Predicate.Logical.Xor
- Rerefined.Predicate.Logical: instance forall k (p :: k) a. Rerefined.Predicate.Refine p a => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Not p) a
- Rerefined.Predicate.Logical: instance forall k (p :: k). Rerefined.Predicate.Predicate p => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Not p)
- Rerefined.Predicate.Logical: instance forall k1 k2 (l :: k1) (r :: k2) (op :: Rerefined.Predicate.Logical.LogicOp). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r, Rerefined.Predicate.Logical.ReifyLogicOp op) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Logical op l r)
- Rerefined.Predicate.Logical: instance forall k1 k2 (l :: k1) a (r :: k2) (op :: Rerefined.Predicate.Logical.LogicOp). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Logical.ReifyLogicOp op) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Logical op l r) a
- Rerefined.Predicate.Logical: reifyLogicOp :: ReifyLogicOp op => (String -> [a] -> Maybe a) -> Maybe a -> Maybe a -> Maybe a
- Rerefined.Predicate.Logical: reifyLogicOpPretty :: ReifyLogicOp op => String
- Rerefined.Predicate.Logical: rerefineDeMorgans1 :: Refined (Not (Logical Or l r)) a -> Refined (Logical And (Not l) (Not r)) a
- Rerefined.Predicate.Logical: rerefineDeMorgans2 :: Refined (Not (Logical And l r)) a -> Refined (Logical Or (Not l) (Not r)) a
- Rerefined.Predicate.Relational: EQ' :: RelOp
- Rerefined.Predicate.Relational: GT' :: RelOp
- Rerefined.Predicate.Relational: GTE :: RelOp
- Rerefined.Predicate.Relational: LT' :: RelOp
- Rerefined.Predicate.Relational: LTE :: RelOp
- Rerefined.Predicate.Relational: NEQ :: RelOp
- Rerefined.Predicate.Relational: data RelOp
- Rerefined.Predicate.Relational.Internal: EQ' :: RelOp
- Rerefined.Predicate.Relational.Internal: GT' :: RelOp
- Rerefined.Predicate.Relational.Internal: GTE :: RelOp
- Rerefined.Predicate.Relational.Internal: LT' :: RelOp
- Rerefined.Predicate.Relational.Internal: LTE :: RelOp
- Rerefined.Predicate.Relational.Internal: NEQ :: RelOp
- Rerefined.Predicate.Relational.Internal: data RelOp
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.EQ'
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.GT'
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.GTE
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.LT'
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.LTE
- Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'Rerefined.Predicate.Relational.Internal.NEQ
- Rerefined.Predicate.Relational.Internal: reifyRelOpPretty :: ReifyRelOp op => String
- Rerefined.Predicate.Relational.Length: instance (Data.Typeable.Internal.Typeable op, GHC.TypeNats.KnownNat n) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Relational.Length.CompareLength op n)
- Rerefined.Predicate.Relational.Length: instance (GHC.TypeNats.KnownNat n, Data.Foldable.Foldable f, Rerefined.Predicate.Relational.Internal.ReifyRelOp op) => Rerefined.Predicate.Refine1 (Rerefined.Predicate.Relational.Length.CompareLength op n) f
- Rerefined.Predicate.Relational.Length: instance (GHC.TypeNats.KnownNat n, Data.MonoTraversable.MonoFoldable a, Rerefined.Predicate.Relational.Internal.ReifyRelOp op) => Rerefined.Predicate.Refine (Rerefined.Predicate.Relational.Length.CompareLength op n) a
- Rerefined.Predicate.Relational.Value: class Typeable sign => ReifySign (sign :: Sign)
- Rerefined.Predicate.Relational.Value: instance (Data.Typeable.Internal.Typeable op, Data.Typeable.Internal.Typeable sign, GHC.TypeNats.KnownNat n) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Relational.Value.CompareValue op sign n)
- Rerefined.Predicate.Relational.Value: instance (GHC.TypeNats.KnownNat n, GHC.Num.Num a, GHC.Classes.Ord a, Rerefined.Predicate.Relational.Internal.ReifyRelOp op, Rerefined.Predicate.Relational.Value.ReifySignedNat sign n, Rerefined.Predicate.Relational.Value.ReifySign sign) => Rerefined.Predicate.Refine (Rerefined.Predicate.Relational.Value.CompareValue op sign n) a
- Rerefined.Predicate.Relational.Value: instance Rerefined.Predicate.Relational.Value.ReifySign 'Rerefined.Predicate.Relational.Value.Neg
- Rerefined.Predicate.Relational.Value: instance Rerefined.Predicate.Relational.Value.ReifySign 'Rerefined.Predicate.Relational.Value.Pos
- Rerefined.Predicate.Relational.Value: signPretty :: ReifySign sign => String
- Rerefined.Predicates: EQ' :: RelOp
- Rerefined.Predicates: GT' :: RelOp
- Rerefined.Predicates: GTE :: RelOp
- Rerefined.Predicates: LT' :: RelOp
- Rerefined.Predicates: LTE :: RelOp
- Rerefined.Predicates: NEQ :: RelOp
- Rerefined.Predicates: data Logical (op :: LogicOp) l r
- Rerefined.Predicates: data RelOp
- Rerefined.Refined1: Refined1 :: f a -> Refined1 p f a
- Rerefined.Refined1: instance forall k (p :: k) (f :: GHC.Types.Type -> GHC.Types.Type). GHC.Base.Functor f => GHC.Base.Functor (Rerefined.Refined1.Refined1 p f)
- Rerefined.Refined1: instance forall k1 (p :: k1) k2 (f :: k2 -> GHC.Types.Type) (a :: k2). GHC.Show.Show (f a) => GHC.Show.Show (Rerefined.Refined1.Refined1 p f a)
- Rerefined.Refined1: instance forall k1 (p :: k1) k2 (f :: k2 -> GHC.Types.Type) (a :: k2). Language.Haskell.TH.Syntax.Lift (f a) => Language.Haskell.TH.Syntax.Lift (Rerefined.Refined1.Refined1 p f a)
- Rerefined.Refined1: newtype Refined1 p f a
- Rerefined.Refined1: unrefine1 :: Refined1 p f a -> f a
+ Rerefined.Predicate: --
+ Rerefined.Predicate: -- Consider using <tt>type-level-show</tt> to build this. However, note
+ Rerefined.Predicate: -- Predicate names should aim to communicate the meaning of the predicate
+ Rerefined.Predicate: -- as clearly and concisely as possible.
+ Rerefined.Predicate: -- constraints in instance contexts.
+ Rerefined.Predicate: -- families in play, so you may need to put <a>KnownSymbol</a>
+ Rerefined.Predicate: -- that GHC cannot figure out <a>KnownSymbol</a> when there are type
+ Rerefined.Predicate: -- | Predicate name.
+ Rerefined.Predicate: instance GHC.Show.Show Rerefined.Predicate.RefineFailure
+ Rerefined.Predicate: type PredicateName (d :: Natural) p :: Symbol;
+ Rerefined.Predicate: }
+ Rerefined.Predicate.Common: class () => IsString a
+ Rerefined.Predicate.Common: data () => Builder
+ Rerefined.Predicate.Common: type KnownPredicateName p = KnownSymbol (PredicateName 0 p)
+ Rerefined.Predicate.Common.Binary: type PredicateNameBOp op prec d l r = ShowParen (d > prec) (PredicateName (prec + 1) l ++ op ++ PredicateName (prec + 1) r)
+ Rerefined.Predicate.Logical: Cont :: kl -> Result kl
+ Rerefined.Predicate.Logical: Cont1 :: Type -> Result kl
+ Rerefined.Predicate.Logical: Done :: Type -> Result kl
+ Rerefined.Predicate.Logical: data And l r
+ Rerefined.Predicate.Logical: data If l r
+ Rerefined.Predicate.Logical: data Iff l r
+ Rerefined.Predicate.Logical: data Nand l r
+ Rerefined.Predicate.Logical: data Nor l r
+ Rerefined.Predicate.Logical: data Or l r
+ Rerefined.Predicate.Logical: data Result kl
+ Rerefined.Predicate.Logical: data Xor l r
+ Rerefined.Predicate.Logical: type family Idk1' p
+ Rerefined.Predicate.Logical.And: data And l r
+ Rerefined.Predicate.Logical.And: eliminateAndLR :: Refined (And l r) a -> Refined r (Refined l a)
+ Rerefined.Predicate.Logical.And: eliminateAndRL :: Refined (And l r) a -> Refined l (Refined r a)
+ Rerefined.Predicate.Logical.And: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.And.And l r)
+ Rerefined.Predicate.Logical.And: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.And.And l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.And.And l r) a
+ Rerefined.Predicate.Logical.And: introduceAndLR :: Refined r (Refined l a) -> Refined (And l r) a
+ Rerefined.Predicate.Logical.And: introduceAndRL :: Refined l (Refined r a) -> Refined (And l r) a
+ Rerefined.Predicate.Logical.And: rerefineAndL :: Refined (And l r) a -> Refined l a
+ Rerefined.Predicate.Logical.And: rerefineAndR :: Refined (And l r) a -> Refined r a
+ Rerefined.Predicate.Logical.If: data If l r
+ Rerefined.Predicate.Logical.If: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.If.If l r)
+ Rerefined.Predicate.Logical.If: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.If.If l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.If.If l r) a
+ Rerefined.Predicate.Logical.Iff: data Iff l r
+ Rerefined.Predicate.Logical.Iff: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Iff.Iff l r)
+ Rerefined.Predicate.Logical.Iff: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Iff.Iff l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Iff.Iff l r) a
+ Rerefined.Predicate.Logical.Nand: data Nand l r
+ Rerefined.Predicate.Logical.Nand: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Nand.Nand l r)
+ Rerefined.Predicate.Logical.Nand: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Nand.Nand l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Nand.Nand l r) a
+ Rerefined.Predicate.Logical.Nor: data Nor l r
+ Rerefined.Predicate.Logical.Nor: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Nor.Nor l r)
+ Rerefined.Predicate.Logical.Nor: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Nor.Nor l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Nor.Nor l r) a
+ Rerefined.Predicate.Logical.Not: data Not p
+ Rerefined.Predicate.Logical.Not: instance forall k (p :: k) a. (Rerefined.Predicate.Refine p a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Not.Not p)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Not.Not p) a
+ Rerefined.Predicate.Logical.Not: instance forall k (p :: k). Rerefined.Predicate.Predicate p => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Not.Not p)
+ Rerefined.Predicate.Logical.Or: data Or l r
+ Rerefined.Predicate.Logical.Or: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Or.Or l r)
+ Rerefined.Predicate.Logical.Or: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Or.Or l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Or.Or l r) a
+ Rerefined.Predicate.Logical.Xor: data Xor l r
+ Rerefined.Predicate.Logical.Xor: instance forall k1 k2 (l :: k1) (r :: k2). (Rerefined.Predicate.Predicate l, Rerefined.Predicate.Predicate r) => Rerefined.Predicate.Predicate (Rerefined.Predicate.Logical.Xor.Xor l r)
+ Rerefined.Predicate.Logical.Xor: instance forall k1 k2 (l :: k1) a (r :: k2). (Rerefined.Predicate.Refine l a, Rerefined.Predicate.Refine r a, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Logical.Xor.Xor l r)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Logical.Xor.Xor l r) a
+ Rerefined.Predicate.Relational: type GTE = GT `Or` EQ
+ Rerefined.Predicate.Relational: type LTE = LT `Or` EQ
+ Rerefined.Predicate.Relational.Internal: -- | Pretty <tt>op</tt>.
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'GHC.Types.EQ
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'GHC.Types.GT
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp 'GHC.Types.LT
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp (Rerefined.Predicate.Logical.Or.Or 'GHC.Types.EQ 'GHC.Types.GT)
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp (Rerefined.Predicate.Logical.Or.Or 'GHC.Types.EQ 'GHC.Types.LT)
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp (Rerefined.Predicate.Logical.Or.Or 'GHC.Types.GT 'GHC.Types.LT)
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp Rerefined.Predicate.Relational.Internal.GTE
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp Rerefined.Predicate.Relational.Internal.LTE
+ Rerefined.Predicate.Relational.Internal: instance Rerefined.Predicate.Relational.Internal.ReifyRelOp Rerefined.Predicate.Relational.Internal.NEQ
+ Rerefined.Predicate.Relational.Internal: type GTE = GT `Or` EQ
+ Rerefined.Predicate.Relational.Internal: type LTE = LT `Or` EQ
+ Rerefined.Predicate.Relational.Internal: type NEQ = LT `Or` GT
+ Rerefined.Predicate.Relational.Internal: type ShowRelOp op :: Symbol;
+ Rerefined.Predicate.Relational.Internal: }
+ Rerefined.Predicate.Relational.Length: instance forall k (n :: GHC.TypeNats.Nat) (f :: GHC.Types.Type -> GHC.Types.Type) (op :: k). (GHC.TypeNats.KnownNat n, Data.Foldable.Foldable f, Rerefined.Predicate.Relational.Internal.ReifyRelOp op, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Relational.Length.CompareLength op n)) => Rerefined.Predicate.Refine1 (Rerefined.Predicate.Relational.Length.CompareLength op n) f
+ Rerefined.Predicate.Relational.Length: instance forall k (n :: GHC.TypeNats.Nat) a (op :: k). (GHC.TypeNats.KnownNat n, Data.MonoTraversable.MonoFoldable a, Rerefined.Predicate.Relational.Internal.ReifyRelOp op, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Relational.Length.CompareLength op n)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Relational.Length.CompareLength op n) a
+ Rerefined.Predicate.Relational.Length: instance forall k (op :: k) (n :: GHC.Num.Natural.Natural). Rerefined.Predicate.Predicate (Rerefined.Predicate.Relational.Length.CompareLength op n)
+ Rerefined.Predicate.Relational.Length: widenCompareLength1 :: forall m op n f a. WROE op n m => Refined1 (CompareLength op n) f a -> Refined1 (CompareLength op m) f a
+ Rerefined.Predicate.Relational.Value: instance forall k (n :: GHC.TypeNats.Nat) a (op :: k) (sign :: Rerefined.Predicate.Relational.Value.Sign). (GHC.TypeNats.KnownNat n, GHC.Num.Num a, GHC.Classes.Ord a, Rerefined.Predicate.Relational.Internal.ReifyRelOp op, Rerefined.Predicate.Relational.Value.ReifySignedNat sign n, Rerefined.Predicate.Common.KnownPredicateName (Rerefined.Predicate.Relational.Value.CompareValue op sign n)) => Rerefined.Predicate.Refine (Rerefined.Predicate.Relational.Value.CompareValue op sign n) a
+ Rerefined.Predicate.Relational.Value: instance forall k (op :: k) (sign :: Rerefined.Predicate.Relational.Value.Sign) (n :: GHC.Num.Natural.Natural). Rerefined.Predicate.Predicate (Rerefined.Predicate.Relational.Value.CompareValue op sign n)
+ Rerefined.Predicate.Relational.Value: type family ShowSign (sign :: Sign) :: Symbol
+ Rerefined.Predicates: data And l r
+ Rerefined.Predicates: data If l r
+ Rerefined.Predicates: data Iff l r
+ Rerefined.Predicates: data Nand l r
+ Rerefined.Predicates: data Nor l r
+ Rerefined.Predicates: data Or l r
+ Rerefined.Predicates: data Xor l r
+ Rerefined.Predicates: type GTE = GT `Or` EQ
+ Rerefined.Predicates: type LTE = LT `Or` EQ
+ Rerefined.Refine: prettyRefineFailure' :: RefineFailure -> Text
+ Rerefined.Refined: Refined1 :: f a -> Refined1 p f a
+ Rerefined.Refined: instance forall k (p :: k) (f :: GHC.Types.Type -> GHC.Types.Type). Data.Foldable.Foldable f => Data.Foldable.Foldable (Rerefined.Refined.Refined1 p f)
+ Rerefined.Refined: instance forall k (p :: k) (f :: GHC.Types.Type -> GHC.Types.Type). Data.Traversable.Traversable f => Data.Traversable.Traversable (Rerefined.Refined.Refined1 p f)
+ Rerefined.Refined: instance forall k (p :: k) (f :: GHC.Types.Type -> GHC.Types.Type). GHC.Base.Functor f => GHC.Base.Functor (Rerefined.Refined.Refined1 p f)
+ Rerefined.Refined: instance forall k1 (p :: k1) k2 (f :: k2 -> GHC.Types.Type) (a :: k2). GHC.Show.Show (f a) => GHC.Show.Show (Rerefined.Refined.Refined1 p f a)
+ Rerefined.Refined: instance forall k1 (p :: k1) k2 (f :: k2 -> GHC.Types.Type) (a :: k2). Language.Haskell.TH.Syntax.Lift (f a) => Language.Haskell.TH.Syntax.Lift (Rerefined.Refined.Refined1 p f a)
+ Rerefined.Refined: newtype Refined1 p f a
+ Rerefined.Refined: squashRefined1 :: Refined1 p f a -> Refined p (f a)
+ Rerefined.Refined: unrefine1 :: Refined1 p f a -> f a
- Rerefined.Predicate: RefineFailure :: a -> a -> [RefineFailure a] -> RefineFailure a
+ Rerefined.Predicate: RefineFailure :: Builder -> Builder -> [RefineFailure] -> RefineFailure
- Rerefined.Predicate: [refineFailureDetail] :: RefineFailure a -> a
+ Rerefined.Predicate: [refineFailureDetail] :: RefineFailure -> Builder
- Rerefined.Predicate: [refineFailureInner] :: RefineFailure a -> [RefineFailure a]
+ Rerefined.Predicate: [refineFailureInner] :: RefineFailure -> [RefineFailure]
- Rerefined.Predicate: [refineFailurePredicate] :: RefineFailure a -> a
+ Rerefined.Predicate: [refineFailurePredicate] :: RefineFailure -> Builder
- Rerefined.Predicate: class Predicate p
+ Rerefined.Predicate: class Predicate p where {
- Rerefined.Predicate: data RefineFailure a
+ Rerefined.Predicate: data RefineFailure
- Rerefined.Predicate: predicateName :: Predicate p => Proxy# p -> Int -> ShowS
+ Rerefined.Predicate: predicateName :: forall p. (Predicate p, KnownSymbol (PredicateName 0 p)) => String
- Rerefined.Predicate: validate :: Refine p a => Proxy# p -> a -> Maybe (RefineFailure String)
+ Rerefined.Predicate: validate :: Refine p a => Proxy# p -> a -> Maybe RefineFailure
- Rerefined.Predicate: validate1 :: Refine1 p f => Proxy# p -> f a -> Maybe (RefineFailure String)
+ Rerefined.Predicate: validate1 :: Refine1 p f => Proxy# p -> f a -> Maybe RefineFailure
- Rerefined.Predicate.Common: validateBool :: Predicate p => Proxy# p -> String -> Bool -> Maybe (RefineFailure String)
+ Rerefined.Predicate.Common: validateBool :: forall p. (Predicate p, KnownPredicateName p) => Proxy# p -> Builder -> Bool -> Maybe RefineFailure
- Rerefined.Predicate.Common: validateFail :: forall p. Predicate p => Proxy# p -> String -> [RefineFailure String] -> Maybe (RefineFailure String)
+ Rerefined.Predicate.Common: validateFail :: forall p. (Predicate p, KnownPredicateName p) => Proxy# p -> Builder -> [RefineFailure] -> Maybe RefineFailure
- Rerefined.Predicate.Relational: data CompareLength (op :: RelOp) (n :: Natural)
+ Rerefined.Predicate.Relational: data CompareLength op (n :: Natural)
- Rerefined.Predicate.Relational: data CompareValue (op :: RelOp) (sign :: Sign) (n :: Natural)
+ Rerefined.Predicate.Relational: data CompareValue op (sign :: Sign) (n :: Natural)
- Rerefined.Predicate.Relational.Internal: class Typeable op => ReifyRelOp (op :: RelOp)
+ Rerefined.Predicate.Relational.Internal: class ReifyRelOp op where {
- Rerefined.Predicate.Relational.Internal: reifyRelOp :: forall a. (ReifyRelOp op, Num a, Ord a) => a -> a -> Bool
+ Rerefined.Predicate.Relational.Internal: reifyRelOp :: forall a. (ReifyRelOp op, Ord a) => a -> a -> Bool
- Rerefined.Predicate.Relational.Internal: type family WidenRelOp (op :: RelOp) (n :: Natural) (m :: Natural)
+ Rerefined.Predicate.Relational.Internal: type family NormalizeOrRelOp op
- Rerefined.Predicate.Relational.Length: data CompareLength (op :: RelOp) (n :: Natural)
+ Rerefined.Predicate.Relational.Length: data CompareLength op (n :: Natural)
- Rerefined.Predicate.Relational.Length: type family WROE' (op :: RelOp) (n :: Natural) (m :: Natural) (b :: Bool)
+ Rerefined.Predicate.Relational.Length: type family WROE' op n m b
- Rerefined.Predicate.Relational.Length: validateCompareLength :: forall op n. (KnownNat n, ReifyRelOp op) => Proxy# (CompareLength op n) -> Int -> Maybe (RefineFailure String)
+ Rerefined.Predicate.Relational.Length: validateCompareLength :: forall op n. (KnownNat n, ReifyRelOp op, KnownPredicateName (CompareLength op n)) => Proxy# (CompareLength op n) -> Int -> Maybe RefineFailure
- Rerefined.Predicate.Relational.Value: data CompareValue (op :: RelOp) (sign :: Sign) (n :: Natural)
+ Rerefined.Predicate.Relational.Value: data CompareValue op (sign :: Sign) (n :: Natural)
- Rerefined.Predicates: data CompareLength (op :: RelOp) (n :: Natural)
+ Rerefined.Predicates: data CompareLength op (n :: Natural)
- Rerefined.Predicates: data CompareValue (op :: RelOp) (sign :: Sign) (n :: Natural)
+ Rerefined.Predicates: data CompareValue op (sign :: Sign) (n :: Natural)
- Rerefined.Refine: data RefineFailure a
+ Rerefined.Refine: data RefineFailure
- Rerefined.Refine: prettyRefineFailure :: (Semigroup a, IsString a) => RefineFailure a -> a
+ Rerefined.Refine: prettyRefineFailure :: RefineFailure -> Text
- Rerefined.Refine: refine :: forall p a. Refine p a => a -> Either (RefineFailure String) (Refined p a)
+ Rerefined.Refine: refine :: forall p a. Refine p a => a -> Either RefineFailure (Refined p a)
- Rerefined.Refine: refine1 :: forall p f a. Refine1 p f => f a -> Either (RefineFailure String) (Refined1 p f a)
+ Rerefined.Refine: refine1 :: forall p f a. Refine1 p f => f a -> Either RefineFailure (Refined1 p f a)

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+## 0.3.0 (2024-05-07)+* refactor predicate names: now handled with a sort of type-level `Show`. no+  `Typeable`, lots of custom prettiness (infix operators!)+* refactor logical predicates, keeping them together doesn't help+* define relational operators using `Ordering` and logical `Or`+* add missing `Foldable`, `Traversable` instances to `Refined1`+* general cleanup+ ## 0.2.0 (2024-05-01) * add missing `Show` instance to `RefineFailure` * add missing `Functor` instance to `Refined1`
README.md view
@@ -38,18 +38,11 @@ See [refined#101](https://github.com/nikita-volkov/refined/issues/101). `Typeable` is useful, but the way it is used brings lots of `Typeable` contexts. -rerefined has predicates declare their "predicate name" explicitly. You can-still use `Typeable` for non-combinator predicates, where no `Typeable` contexts-are incurred, but combinator predicates such as binary logical predicates-require more work. However, you can use all the existing `ShowS` helpers (that's-how `typeRep`s are printed anyway), so it's just like writing a manual `Show`-instance! Plus, combinator predicates are fairly unusual, so library users will-probably never see this.--Note that this change also improves predicate name display, since `typeRep`-tries to display inferred/hidden kinds for wrapped predicates in combinator-predicates, which are uninteresting. We can ignore these in our manual-instances!+rerefined asks that you do a bit more work upfront, but gives you tools and+grants much more power. Predicates declare their "predicate name" explicitly as+a type-level `Symbol`. Precedence is supported and infix operators are welcomed.+(For now, the logical operators primarily look like their propositional logic+counterparts.)  ### Cleaner design What do `LessThan`, `GreaterThan`, `EqualTo` etc. have in common? They're all
rerefined.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           rerefined-version:        0.2.0+version:        0.3.0 synopsis:       Refinement types, again description:    Please see README.md. category:       Types, Data@@ -16,6 +16,10 @@ license:        MIT license-file:   LICENSE build-type:     Simple+tested-with:+    GHC==9.8+  , GHC==9.6+  , GHC==9.4 extra-source-files:     README.md     CHANGELOG.md@@ -29,20 +33,28 @@       Rerefined       Rerefined.Predicate       Rerefined.Predicate.Common+      Rerefined.Predicate.Common.Binary       Rerefined.Predicate.Fail       Rerefined.Predicate.Logical+      Rerefined.Predicate.Logical.And+      Rerefined.Predicate.Logical.Equivalences+      Rerefined.Predicate.Logical.If+      Rerefined.Predicate.Logical.Iff+      Rerefined.Predicate.Logical.Nand+      Rerefined.Predicate.Logical.Nor+      Rerefined.Predicate.Logical.Not+      Rerefined.Predicate.Logical.Or+      Rerefined.Predicate.Logical.Xor       Rerefined.Predicate.Relational       Rerefined.Predicate.Relational.Internal       Rerefined.Predicate.Relational.Length       Rerefined.Predicate.Relational.Value       Rerefined.Predicate.Succeed       Rerefined.Predicates-      Rerefined.Predicates.RefinedShim       Rerefined.Refine       Rerefined.Refine.TH       Rerefined.Refine.Unsafe       Rerefined.Refined-      Rerefined.Refined1   other-modules:       Paths_rerefined   hs-source-dirs:@@ -60,8 +72,10 @@       MagicHash   ghc-options: -Wall -Wno-unticked-promoted-constructors   build-depends:-      base >=4.16 && <5+      base >=4.17 && <5     , mono-traversable >=1.0.17.0 && <1.1-    , template-haskell-    , typeably >=0.1.0 && <0.2+    , template-haskell >=2.19.0.0 && <2.22+    , text >=2.0 && <2.2+    , text-builder-linear >=0.1.2 && <0.2+    , type-level-show >=0.1.0 && <0.2   default-language: GHC2021
src/Rerefined/Predicate.hs view
@@ -1,40 +1,50 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+ -- | Base definitions for refinement predicates.  module Rerefined.Predicate   ( Refine(validate)   , Refine1(validate1)   , RefineFailure(..)-  , Predicate(predicateName)+  , Predicate(..)+  , predicateName   ) where -import GHC.Exts ( Proxy# )-import Data.Typeable ( Typeable, typeRep )-import Data.Typeable.Typeably-import Data.Proxy ( Proxy(Proxy) )+import GHC.Exts ( Proxy#, proxy# )+import Data.Text.Builder.Linear qualified as TBL+import GHC.TypeLits ( Natural, Symbol, KnownSymbol, symbolVal' )  -- | Types which define refinements on other types. class Predicate p where-    -- | The predicate name, as a 'Show'-like (for good bracketing).+    -- | Predicate name.     ---    -- Non-combinator predicates may derive this via 'Typeably'. Combinator-    -- predicates must write a 'Show'-like instance manually, in order to avoid-    -- incurring insidious 'Typeable' contexts for the wrapped predicate(s).-    -- (TODO figure out some generics and/or TH to resolve that)-    predicateName :: Proxy# p -> Int -> ShowS+    -- Predicate names should aim to communicate the meaning of the predicate as+    -- clearly and concisely as possible.+    --+    -- Consider using @type-level-show@ to build this. However, note that GHC+    -- cannot figure out 'KnownSymbol' when there are type families in play, so+    -- you may need to put 'KnownSymbol' constraints in instance contexts.+    type PredicateName (d :: Natural) p :: Symbol+        -- ^ TODO d: the operator precedence of the enclosing context (a number+        --   from 0 to 11). Function application has precedence 10. --- | Fill out predicate metadata using its 'Typeable' instance.------ Do not use this for combinator predicates. Doing so will incur insidious--- 'Typeable' contexts for the wrapped predicate(s).-instance Typeable a => Predicate (Typeably a) where-    predicateName _ d = showsPrec d (typeRep (Proxy @a))+{- TODO+stuffing the KnownSymbol constraint into a Predicate superclass is handy, but+then we have to handle it in combinator predicates. probably _not_ doing so is+better, so I'm trying that first.+-} +-- | Reify predicate name.+predicateName+    :: forall p. (Predicate p, KnownSymbol (PredicateName 0 p)) => String+predicateName = symbolVal' (proxy# @(PredicateName 0 p))+ -- | Refine @a@ with predicate @p@. class Predicate p => Refine p a where     -- | Validate predicate @p@ for the given @a@.     --     -- 'Nothing' indicates success. 'Just' contains a validation failure.-    validate :: Proxy# p -> a -> Maybe (RefineFailure String)+    validate :: Proxy# p -> a -> Maybe RefineFailure  -- | Refine functor type @f@ with functor predicate @p@. --@@ -43,20 +53,20 @@ -- structure, and not the stored elements. class Predicate p => Refine1 p f where     -- | Validate predicate @p@ for the given @f a@.-    validate1 :: Proxy# p -> f a -> Maybe (RefineFailure String)+    validate1 :: Proxy# p -> f a -> Maybe RefineFailure  -- | Predicate validation failure.------ Polymorphic over the message type because I want to use 'Text', but want it--- doesn't have the convenient 'Show' internals that 'String' does.-data RefineFailure a = RefineFailure-  { refineFailurePredicate :: a-  -- ^ The predicate that failed.+data RefineFailure = RefineFailure+  { refineFailurePredicate :: TBL.Builder+  -- ^ The name of the predicate that failed.+  --+  -- Obtained via 'predicateName'. -  , refineFailureDetail    :: a-  -- ^ Failure clarification.+  , refineFailureDetail    :: TBL.Builder+  -- ^ Precise failure detail e.g. which of the inner predicates of an @And@+  --   combinator predicate failed. -  , refineFailureInner     :: [RefineFailure a]+  , refineFailureInner     :: [RefineFailure]   -- ^ Any wrapped errors, for combinator predicates.   --   -- What these are, and their order, should be noted in 'refineFailureDetail'.
src/Rerefined/Predicate/Common.hs view
@@ -6,45 +6,38 @@   (   -- * Re-exports     module Rerefined.Predicate-  , Typeably(..), Typeable   , proxy#+  , TBL.Builder+  , IsString -- TODO remove    -- * Predicate validation   , validateFail, validateBool--  -- * Predicate name-  , predicateName1, predicateName2+  , KnownPredicateName   ) where  import Rerefined.Predicate-import GHC.Exts ( Proxy#, proxy# )-import Data.Typeable.Typeably-import Data.Typeable ( Typeable )+import GHC.Exts ( Proxy#, proxy#, IsString(fromString) )+import GHC.TypeLits ( KnownSymbol )+import Data.Text.Builder.Linear qualified as TBL +-- TODO maybe move to main 'Rerefined.Predicate' module+type KnownPredicateName p = KnownSymbol (PredicateName 0 p)+ -- | Shortcut for returning a predicate validation failure. validateFail     :: forall p-    .  Predicate p-    => Proxy# p -> String -> [RefineFailure String]-    -> Maybe (RefineFailure String)-validateFail p msg es = Just $ RefineFailure (predicateName p 0 "") msg es+    .  (Predicate p, KnownPredicateName p)+    => Proxy# p -> TBL.Builder -> [RefineFailure]+    -> Maybe RefineFailure+validateFail _p msg es =+    Just $ RefineFailure (fromString $ predicateName @p) msg es  -- | Shortcut for simply validating a 'Bool'. validateBool-    :: Predicate p => Proxy# p -> String -> Bool-    -> Maybe (RefineFailure String)+    :: forall p+    .  (Predicate p, KnownPredicateName p)+    => Proxy# p -> TBL.Builder -> Bool+    -> Maybe RefineFailure validateBool p e = \case   True  -> Nothing   False -> validateFail p e []--predicateName1 :: forall p. Predicate p => String -> Int -> ShowS-predicateName1 pName d = showParen (d > 10) $-      showString pName . showChar ' '-    . predicateName (proxy# @p) 11--predicateName2-    :: forall l r. (Predicate l, Predicate r) => String -> Int -> ShowS-predicateName2 pName d = showParen (d > 10) $-      showString pName . showChar ' '-    . predicateName (proxy# @l) 11 . showChar ' '-    . predicateName (proxy# @r) 11
+ src/Rerefined/Predicate/Common/Binary.hs view
@@ -0,0 +1,13 @@+-- | Common utilities for binary combinator predicates.++module Rerefined.Predicate.Common.Binary where++import Rerefined.Predicate+import TypeLevelShow.Utils+import GHC.TypeNats++-- | Render a binary combinator predicate with an infix operator.+--+-- The operator must include the left and right spaces.+type PredicateNameBOp op prec d l r = ShowParen (d > prec)+    (PredicateName (prec+1) l ++ op ++ PredicateName (prec+1) r)
src/Rerefined/Predicate/Fail.hs view
@@ -1,9 +1,10 @@+{-# LANGUAGE OverloadedStrings #-}+ module Rerefined.Predicate.Fail where  import Rerefined.Predicate.Common  -- | Always fails.-data Fail deriving Predicate via Typeably Fail--instance Refine Fail a where-    validate p _ = validateFail p "fail" []+data Fail+instance Predicate Fail where type PredicateName d Fail = "⊥"+instance Refine Fail a where validate p _ = validateFail p "fail" []
src/Rerefined/Predicate/Logical.hs view
@@ -1,138 +1,41 @@-{-# LANGUAGE AllowAmbiguousTypes #-}--module Rerefined.Predicate.Logical where--import Rerefined.Predicate.Common-import Rerefined.Refined-import Rerefined.Refine.Unsafe---- | Logical binary operator.------ No need to disambiguate that these are binary operators, because there's only--- one logical unary operator 'Not'.-data LogicOp = And | Or | Nand | Nor | Xor | Xnor---- | A logical binary operation on two predicates.-data Logical (op :: LogicOp) l r---- TODO could do whatever we want here e.g. infix. (but idk what e.g. XNOR uses)-instance (Predicate l, Predicate r, ReifyLogicOp op)-  => Predicate (Logical op l r) where-    predicateName _ d = showParen (d > 10) $-          showString "Logical "-        . showString (reifyLogicOpPretty @op) . showChar ' '-        . predicateName (proxy# @l) 11 . showChar ' '-        . predicateName (proxy# @r) 11--instance (Refine l a, Refine r a, ReifyLogicOp op)-  => Refine (Logical op l r) a where-    validate p a =-        reifyLogicOp @op (validateFail p)-            (validate (proxy# @l) a)-            (validate (proxy# @r) a)---- | Reify a logical binary operator type tag.-class ReifyLogicOp (op :: LogicOp) where-    reifyLogicOpPretty :: String-    reifyLogicOp-        :: (String -> [a] -> Maybe a)-        -> Maybe a-        -> Maybe a-        -> Maybe a--instance ReifyLogicOp And where-    reifyLogicOpPretty = "And"-    reifyLogicOp fFail l r =-        case l of-          Nothing ->-            case r of-              Nothing -> Nothing-              Just er -> fFail "AND:  right failed"    [    er]-          Just el ->-            case r of-              Nothing -> fFail "AND:   left failed"    [el    ]-              Just er -> fFail "AND:    l&r failed"    [el, er]--instance ReifyLogicOp Or where-    reifyLogicOpPretty = "Or"-    reifyLogicOp fFail l r =-        case l of-          Nothing -> Nothing-          Just el ->-            case r of-              Nothing -> Nothing-              Just er -> fFail "OR:     l&r failed"    [el, er]--instance ReifyLogicOp Nand where-    reifyLogicOpPretty = "Nand"-    reifyLogicOp fFail l r =-        case l of-          Just _  -> Nothing-          Nothing ->-            case r of-              Just _  -> Nothing-              Nothing -> fFail "NAND:   l&r succeeded" [      ]--instance ReifyLogicOp Nor where-    reifyLogicOpPretty = "Nor"-    reifyLogicOp fFail l r =-        case l of-          Just el ->-            case r of-              Just _  -> Nothing-              Nothing -> fFail "NOR:  right succeeded" [el    ]-          Nothing ->-            case r of-              Just er -> fFail "NOR:   left succeeded" [    er]-              Nothing -> fFail "NOR:    l&r succeeded" [      ]--instance ReifyLogicOp Xor where-    reifyLogicOpPretty = "Xor"-    reifyLogicOp fFail l r =-        case l of-          Nothing ->-            case r of-              Just _  -> Nothing-              Nothing -> fFail "XOR:    l&r succeeded" [      ]-          Just el ->-            case r of-              Nothing -> Nothing-              Just er -> fFail "XOR:    l&r failed"    [el, er]+{-# LANGUAGE UndecidableInstances #-} -- TODO TMP -instance ReifyLogicOp Xnor where-    reifyLogicOpPretty = "Xnor"-    reifyLogicOp fFail l r =-        case l of-          Nothing ->-            case r of-              Nothing -> Nothing-              Just er -> fFail "XNOR: right failed"    [    er]-          Just el ->-            case r of-              Just _  -> Nothing-              Nothing -> fFail "XNOR:  left failed"    [el    ]+module Rerefined.Predicate.Logical+  ( And, Iff, If, Nand, Nor, Not, Or, Xor+  , NormalizeLogicalStep+  , NormalizeLogical1Step+  , Result(..), Idk1'+  ) where -data Not p+import Rerefined.Predicate.Logical.And+import Rerefined.Predicate.Logical.Iff+import Rerefined.Predicate.Logical.If+import Rerefined.Predicate.Logical.Nand+import Rerefined.Predicate.Logical.Nor+import Rerefined.Predicate.Logical.Not+import Rerefined.Predicate.Logical.Or+import Rerefined.Predicate.Logical.Xor -instance Predicate p => Predicate (Not p) where-    predicateName _ = predicateName1 @p "Not"+import Data.Kind ( Type )+-- left = continue, right = normalized+type NormalizeLogicalStep :: (kl -> kr -> Type) -> kl -> kr -> Result kl+type family NormalizeLogicalStep op l r where+    NormalizeLogicalStep Or   l l = Cont  l+    NormalizeLogicalStep And  l l = Cont  l+    NormalizeLogicalStep Nand l l = Cont1 (Not l)+    NormalizeLogicalStep op   l r = Done (op l r) -instance Refine p a => Refine (Not p) a where-    validate p a =-        case validate (proxy# @p) a of-          Just _  -> Nothing-          Nothing -> validateFail p "NOT: predicate succeeded" []+data Result kl = Done Type | Cont kl | Cont1 Type --- TODO principle of explosion? (p and not p -> anything)+type NormalizeLogical1Step :: (k -> Type) -> k -> Result k+type family NormalizeLogical1Step op p where+    NormalizeLogical1Step Not (Not p) = Cont p+    NormalizeLogical1Step op  p       = Done (op p) --- TODO-rerefineDeMorgans1-    :: Refined (Not (Logical Or  l r))       a-    -> Refined (Logical And (Not l) (Not r)) a-rerefineDeMorgans1 = unsafeRerefine+type family Idk1 res where+    Idk1 (Cont p) = Idk1' p+    Idk1 (Done p) = p --- TODO-rerefineDeMorgans2-    :: Refined (Not (Logical And l r))       a-    -> Refined (Logical Or  (Not l) (Not r)) a-rerefineDeMorgans2 = unsafeRerefine+type family Idk1' p where+    Idk1' (Not p) = Idk1 (NormalizeLogical1Step Not p)+    Idk1' p = p
+ src/Rerefined/Predicate/Logical/And.hs view
@@ -0,0 +1,56 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.And where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common+import Rerefined.Refine.Unsafe+import Rerefined.Refined++-- | Logical conjunction. Also AND logic gate.+data And l r++-- | Precendence of 3 (matching 'Data.Bool.&&').+instance (Predicate l, Predicate r) => Predicate (And l r) where+    type PredicateName d (And l r) = PredicateNameBOp " ∧ " 3 d l r++instance (Refine l a, Refine r a, KnownPredicateName (And l r))+  => Refine (And l r) a where+    validate p a =+        case l of+          Nothing ->+            case r of+              Nothing -> Nothing+              Just er -> validateFail p "AND:  right failed"    [er    ]+          Just el ->+            case r of+              Nothing -> validateFail p "AND:   left failed"    [    el]+              Just er -> validateFail p "AND:    l&r failed"    [er, el]+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a++-- | Take just the left predicate from an 'And'.+rerefineAndL :: Refined (And l r) a -> Refined l a+rerefineAndL = unsafeRerefine++-- | Take just the right predicate from an 'And'.+rerefineAndR :: Refined (And l r) a -> Refined r a+rerefineAndR = unsafeRerefine++-- | Eliminate an 'And' by applying the left predicate, then the right.+eliminateAndLR :: Refined (And l r) a -> Refined r (Refined l a)+eliminateAndLR = unsafeRefine . unsafeRefine . unrefine++-- | Eliminate an 'And' by applying the right predicate, then the left.+eliminateAndRL :: Refined (And l r) a -> Refined l (Refined r a)+eliminateAndRL = unsafeRefine . unsafeRefine . unrefine++-- | Introduce an 'And' given a double-'Refined'. Inner is left.+introduceAndLR :: Refined r (Refined l a) -> Refined (And l r) a+introduceAndLR = unsafeRefine . unrefine . unrefine++-- | Introduce an 'And' given a double-'Refined'. Inner is right.+introduceAndRL :: Refined l (Refined r a) -> Refined (And l r) a+introduceAndRL = unsafeRefine . unrefine . unrefine
+ src/Rerefined/Predicate/Logical/Equivalences.hs view
@@ -0,0 +1,19 @@+-- | Logical equivalences.++module Rerefined.Predicate.Logical.Equivalences where++{-++-- TODO+rerefineDeMorgans1+    :: Refined (Not (Logical Or  l r))       a+    -> Refined (Logical And (Not l) (Not r)) a+rerefineDeMorgans1 = unsafeRerefine++-- TODO+rerefineDeMorgans2+    :: Refined (Not (Logical And l r))       a+    -> Refined (Logical Or  (Not l) (Not r)) a+rerefineDeMorgans2 = unsafeRerefine++-}
+ src/Rerefined/Predicate/Logical/If.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.If where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | Logical implication. "If l then r".+data If l r++-- | Precendence of 4 (matching '==').+instance (Predicate l, Predicate r) => Predicate (If l r) where+    -- TODO double arrow? idk+    type PredicateName d (If l r) = PredicateNameBOp " → " 4 d l r++instance (Refine l a, Refine r a, KnownPredicateName (If l r))+  => Refine (If l r) a where+    validate p a =+        case l of+          Just _  -> Nothing+          Nothing ->+            case r of+              Nothing -> Nothing+              Just er ->+                validateFail p "IF: left succeeded, but right failed" [er]+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
+ src/Rerefined/Predicate/Logical/Iff.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Iff where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | Logical biconditional ("if and only if"). Also the XNOR logic gate, or+--   equivalence (loosely).+data Iff l r++-- | Precendence of 4 (matching '==').+instance (Predicate l, Predicate r) => Predicate (Iff l r) where+    type PredicateName d (Iff l r) = PredicateNameBOp " ↔ " 4 d l r++instance (Refine l a, Refine r a, KnownPredicateName (Iff l r))+  => Refine (Iff l r) a where+    validate p a =+        case l of+          Nothing ->+            case r of+              Nothing -> Nothing+              Just er ->+                validateFail p "IFF: left succeeded, but right failed" [er]+          Just el ->+            case r of+              Just _  -> Nothing+              Nothing ->+                validateFail p "IFF: left failed, but right succeeded" [el]+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
+ src/Rerefined/Predicate/Logical/Nand.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Nand where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | NAND logic gate. Also called the Sheffer stroke, or non-conjunction.+data Nand l r++-- | Precendence of 3 (matching 'Data.Bool.&&').+instance (Predicate l, Predicate r) => Predicate (Nand l r) where+    type PredicateName d (Nand l r) = PredicateNameBOp " ⊼ " 3 d l r++instance (Refine l a, Refine r a, KnownPredicateName (Nand l r))+  => Refine (Nand l r) a where+    validate p a =+        case l of+          Just _  -> Nothing+          Nothing ->+            case r of+              Just _  -> Nothing+              Nothing -> validateFail p "NAND: l&r succeeded" []+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
+ src/Rerefined/Predicate/Logical/Nor.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Nor where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | NOR logic gate. Also called non-disjunction, or joint denial.+data Nor l r++-- | Precendence of 2 (matching 'Data.Bool.||').+instance (Predicate l, Predicate r) => Predicate (Nor l r) where+    type PredicateName d (Nor l r) = PredicateNameBOp " ⊽ " 2 d l r++instance (Refine l a, Refine r a, KnownPredicateName (Nor l r))+  => Refine (Nor l r) a where+    validate p a =+        case l of+          Just _ ->+            case r of+              Just _  -> Nothing+              Nothing -> validateFail p "NOR: left succeeded"  []+          Nothing ->+            case r of+              Just _  -> validateFail p "NOR: right succeeded" []+              Nothing -> validateFail p "NOR: l&r succeeded"   []+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
+ src/Rerefined/Predicate/Logical/Not.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Not where++import Rerefined.Predicate.Common+import TypeLevelShow.Utils++-- | Logical negation. Also NOT logic gate, or logical complement.+data Not p++-- | Precendence of 9 (one below function application).+instance Predicate p => Predicate (Not p) where+    type PredicateName d (Not p) = ShowParen (d > 9)+        ("¬ " ++ PredicateName 10 p)++instance (Refine p a, KnownPredicateName (Not p))+  => Refine (Not p) a where+    validate p a =+        case validate (proxy# @p) a of+          Just _  -> Nothing+          Nothing -> validateFail p "NOT: predicate succeeded" []
+ src/Rerefined/Predicate/Logical/Or.hs view
@@ -0,0 +1,27 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Or where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | Logical disjunction. Also OR logic gate.+data Or l r++-- | Precendence of 2 (matching 'Data.Bool.||').+instance (Predicate l, Predicate r) => Predicate (Or l r) where+    type PredicateName d (Or l r) = PredicateNameBOp " ∨ " 2 d l r++instance (Refine l a, Refine r a, KnownPredicateName (Or l r))+  => Refine (Or l r) a where+    validate p a =+        case l of+          Nothing -> Nothing+          Just el ->+            case r of+              Nothing -> Nothing+              Just er -> validateFail p "OR: l&r failed" [er, el]+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
+ src/Rerefined/Predicate/Logical/Xor.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE UndecidableInstances #-} -- for easier PredicateName+{-# LANGUAGE OverloadedStrings #-} -- for builder++module Rerefined.Predicate.Logical.Xor where++import Rerefined.Predicate.Common.Binary+import Rerefined.Predicate.Common++-- | Logical exclusive disjunction. Also XOR logic gate.+data Xor l r++-- | Precendence of 4 (matching '==').+instance (Predicate l, Predicate r) => Predicate (Xor l r) where+    type PredicateName d (Xor l r) = PredicateNameBOp " ⊕ " 4 d l r++instance (Refine l a, Refine r a, KnownPredicateName (Xor l r))+  => Refine (Xor l r) a where+    validate p a =+        case l of+          Nothing ->+            case r of+              Just _  -> Nothing+              Nothing -> validateFail p "XOR: l&r succeeded" [      ]+          Just el ->+            case r of+              Nothing -> Nothing+              Just er -> validateFail p "XOR: l&r failed"    [er, el]+      where+        l = validate (proxy# @l) a+        r = validate (proxy# @r) a
src/Rerefined/Predicate/Relational.hs view
@@ -1,8 +1,8 @@ module Rerefined.Predicate.Relational   ( CompareValue   , Sign(..)-  , RelOp(..)   , CompareLength+  , LTE, GTE   ) where  import Rerefined.Predicate.Relational.Internal
src/Rerefined/Predicate/Relational/Internal.hs view
@@ -1,75 +1,111 @@-{-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE UndecidableInstances #-} -- for weird TODO stuff+{-# LANGUAGE AllowAmbiguousTypes #-}  -- for ReifyRelOp+{-# LANGUAGE UndecidableInstances #-} -- for WidenRelOp -module Rerefined.Predicate.Relational.Internal where+{- | Relational operator definitions. -import Data.Typeable ( Typeable )+Haskell base exports the type 'Ordering', which is an enum that states the+result of comparing two 'Ord's. We can utilize this to define /relational+operators/: +* 'LT', 'EQ' and 'GT' already map to relational operators.+* The others can be defined by combining the above with 'Or'. e.g. @'LT' ``Or``+  'EQ'@ -> "less than or equal" ('<=')++What's the point? We save on definitions, and get to reuse well-known data types+which most users will have intuition for. We do have to contest with+commutativity, but this is an extremely minor concern which can only come up if+you don't use the provided type synonyms, or do lots of type-level predicate+manipulation. And we provide those swapped-order instances anyway!+-}++module Rerefined.Predicate.Relational.Internal where++import Rerefined.Predicate.Logical.Or import GHC.TypeNats import Data.Type.Ord ( OrdCond )+import GHC.TypeLits ( Symbol ) --- | Relational operator.------ There are three possible outcomes from 'compare'ing two terms, defined in--- 'Ordering'. However, we may instead compare terms using relational operators--- such as @>=@, which are more specific comparisons that return a 'Bool'.------ Constructor order is arbitrary due to @NEQ@, which obstructs ordering in a--- meaningful way.-data RelOp-  = LT' -- ^ '<'  less than-  | LTE -- ^ '<=' less than or equal to-  | EQ' -- ^ '=='              equal to-  | NEQ -- ^ '/=' less than or             greater than-  | GTE -- ^ '>='              equal to or greater than-  | GT' -- ^ '>'                           greater than+import Data.Kind ( Type ) +type LTE = LT `Or` EQ++-- | "not equal to" is equivalent to "strictly less than or greater than". We+--   could use 'Rerefined.Predicate.Logical.Not.Not', but sticking with just+--   'Or' keeps the internals simple.+type NEQ = LT `Or` GT++type GTE = GT `Or` EQ+ -- | Reify a relational operator type tag. ----- We stuff the 'Typeable' constraint in here because we need it for easy--- 'Rerefined.Predicate.Predicate' instances, and we don't want to expose the--- 'Typeable' constraint elsewhere.-class Typeable op => ReifyRelOp (op :: RelOp) where-    -- | The term-level relational operator that @op@ describes.-    reifyRelOp :: forall a. (Num a, Ord a) => a -> a -> Bool+-- Permitted operators are @Ordering@ constructors 'LT', 'EQ' and 'GT'; and+-- combinations of these using 'Or'.+class ReifyRelOp op where+    -- | Pretty @op@.+    type ShowRelOp op :: Symbol -    -- | Pretty operator.-    reifyRelOpPretty :: String+    -- | The term-level relational operator that @op@ describes.+    reifyRelOp :: forall a. Ord a => a -> a -> Bool -instance ReifyRelOp LT' where+instance ReifyRelOp LT where+    type ShowRelOp LT = "<"     reifyRelOp = (<)-    reifyRelOpPretty = "<"  instance ReifyRelOp LTE where+    type  ShowRelOp LTE = "<="     reifyRelOp = (<=)-    reifyRelOpPretty = "<=" -instance ReifyRelOp EQ' where+-- | Hidden instance. You won't see this if you use the type synonyms.+deriving via LTE instance ReifyRelOp (EQ `Or` LT)++instance ReifyRelOp EQ where+    type  ShowRelOp EQ = "=="     reifyRelOp = (==)-    reifyRelOpPretty = "=="  instance ReifyRelOp NEQ where+    type  ShowRelOp NEQ = "/="     reifyRelOp = (/=)-    reifyRelOpPretty = "/=" +-- | Hidden instance. You won't see this if you use the type synonyms.+deriving via NEQ instance ReifyRelOp (GT `Or` LT)+ instance ReifyRelOp GTE where+    type ShowRelOp GTE = ">="     reifyRelOp = (>=)-    reifyRelOpPretty = ">=" -instance ReifyRelOp GT' where+-- | Hidden instance. You won't see this if you use the type synonyms.+deriving via GTE instance ReifyRelOp (EQ `Or` GT)++instance ReifyRelOp GT where+    type ShowRelOp GT = ">"     reifyRelOp = (>)-    reifyRelOpPretty = ">" --- | Can we widen the given 'RelOp' from @n@ to @m@?-type family WidenRelOp (op :: RelOp) (n :: Natural) (m :: Natural) where+-- | Can we widen the given 'RelOp' on the given 'Natural' from @n@ to @m@?+type WidenRelOp :: k -> Natural -> Natural -> Bool+type family WidenRelOp op n m where     -- @n == m@? no problem     WidenRelOp op  n n = True      -- I'd love to simplify this, but 'CmpNat' is opaque.-    WidenRelOp LT' n m = OrdCond (CmpNat n m) True  True False+    WidenRelOp LT  n m = OrdCond (CmpNat n m) True  True False     WidenRelOp LTE n m = OrdCond (CmpNat n m) True  True False     WidenRelOp GTE n m = OrdCond (CmpNat n m) False True True-    WidenRelOp GT' n m = OrdCond (CmpNat n m) False True True+    WidenRelOp GT  n m = OrdCond (CmpNat n m) False True True +    -- | swapped LTE, lower down in equation list because less common+    WidenRelOp (EQ `Or` LT) n m =+        OrdCond (CmpNat n m) True  True False++    -- | swapped GTE, lower down in equation list because less common+    WidenRelOp (EQ `Or` GT) n m =+        OrdCond (CmpNat n m) False True True+     -- can't widen (==) or (/=)     WidenRelOp _   _ _ = False++-- this gets clumsier due to kinding clashes (k vs. Ordering)+type NormalizeOrRelOp :: Type -> Type+type family NormalizeOrRelOp op where+    NormalizeOrRelOp (EQ `Or` LT) = LTE+    NormalizeOrRelOp (GT `Or` LT) = NEQ+    NormalizeOrRelOp (EQ `Or` GT) = GTE
src/Rerefined/Predicate/Relational/Length.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE UndecidableInstances #-} -- for GHC <= 9.4, WROE+ module Rerefined.Predicate.Relational.Length where  import Rerefined.Predicate.Common@@ -6,34 +9,45 @@ import Data.MonoTraversable ( MonoFoldable(olength) ) import GHC.Exts ( Proxy# ) -import Rerefined.Refined-import Rerefined.Refine.Unsafe ( unsafeRerefine )+import Rerefined.Refine.Unsafe import GHC.TypeError import Data.Kind ( type Constraint )+import TypeLevelShow.Utils+import TypeLevelShow.Natural+import Data.Text.Builder.Linear qualified as TBL  -- | Compare length to a type-level 'Natural' using the given 'RelOp'.-data CompareLength (op :: RelOp) (n :: Natural)-    deriving Predicate via Typeably (CompareLength op n)+data CompareLength op (n :: Natural) +-- | Precedence of 4 (matching base relational operators e.g. '>=').+instance Predicate (CompareLength op n) where+    type PredicateName d (CompareLength op n) = ShowParen (d > 4)+        ("Length " ++ ShowRelOp op ++ ShowChar ' ' ++ ShowNatDec n)+ -- | Compare the length of a 'Foldable' to a type-level 'Natural' using the --   given 'RelOp'.-instance (KnownNat n, Foldable f, ReifyRelOp op)-  => Refine1 (CompareLength op n) f where+instance+  ( KnownNat n, Foldable f, ReifyRelOp op+  , KnownPredicateName (CompareLength op n)+  ) => Refine1 (CompareLength op n) f where     validate1 p = validateCompareLength p . length  -- | Compare the length of a 'MonoFoldable' to a type-level 'Natural' using the --   given 'RelOp'.-instance (KnownNat n, MonoFoldable a, ReifyRelOp op)-  => Refine (CompareLength op n) a where+instance+  ( KnownNat n, MonoFoldable a, ReifyRelOp op+  , KnownPredicateName (CompareLength op n)+  ) => Refine (CompareLength op n) a where     validate p = validateCompareLength p . olength  validateCompareLength-    :: forall op n. (KnownNat n, ReifyRelOp op)-    => Proxy# (CompareLength op n) -> Int -> Maybe (RefineFailure String)+    :: forall op n+    .  ( KnownNat n, ReifyRelOp op+       , KnownPredicateName (CompareLength op n)+    ) => Proxy# (CompareLength op n) -> Int -> Maybe RefineFailure validateCompareLength p len =-    validateBool p ("length not "<>reifyRelOpPretty @op<>" "<>show n)-        (reifyRelOp @op len (fromIntegral n))-  where n = natVal' (proxy# @n)+    validateBool p ("length: "<>TBL.fromDec n) (reifyRelOp @op len n)+  where n = fromIntegral (natVal' (proxy# @n))  -- | Widen a length comparison predicate. --@@ -51,9 +65,25 @@     -> Refined (CompareLength op m) a widenCompareLength = unsafeRerefine +-- | Widen a length comparison predicate.+--+-- Only valid widenings are permitted, checked at compile time.+--+-- Example: Given a >= 1, we know also that a >= 0. Thus, this function allows+-- you to turn a @Refined1 (CompareLength GTE 1) f a@ into a @Refined1+-- (CompareLength GTE 0) f a@.+--+-- TODO improve type error here+widenCompareLength1+    :: forall m op n f a+    .  WROE op n m+    => Refined1 (CompareLength op n) f a+    -> Refined1 (CompareLength op m) f a+widenCompareLength1 = unsafeRerefine1+ type WROE op n m = WROE' op n m (WidenRelOp op n m)-type WROE' :: RelOp -> Natural -> Natural -> Bool -> Constraint-type family WROE' (op :: RelOp) (n :: Natural) (m :: Natural) (b :: Bool) where+type WROE' :: k -> Natural -> Natural -> Bool -> Constraint+type family WROE' op n m b where     WROE' op n m True  = ()     WROE' op n m False = TypeError       (      Text "can't widen relational equation "
src/Rerefined/Predicate/Relational/Value.hs view
@@ -1,44 +1,42 @@-{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE UndecidableInstances #-} -- for PredicateName+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE AllowAmbiguousTypes #-} -- for signPretty  module Rerefined.Predicate.Relational.Value where  import Rerefined.Predicate.Common import Rerefined.Predicate.Relational.Internal import GHC.TypeNats ( Natural, KnownNat, natVal' )+import TypeLevelShow.Utils+import TypeLevelShow.Natural+import GHC.TypeLits ( Symbol )  -- | Compare value to a type-level 'Natural' using the given 'RelOp'.-data CompareValue (op :: RelOp) (sign :: Sign) (n :: Natural)-    deriving Predicate via Typeably (CompareValue op sign n)--- TODO I could write custom predicateNames here if I wanted to override how--- they display. But I don't mind the expanded type synonyms. @CompareValue--- 'CBOpLT 10@ still makes sense to me, especially with the extra message.------ I should simplify op names, but not sure what to, since I can't use LT/EQ/GT.-{--instance KnownNat n => Predicate (LessThan n) where-    predicateName d = showParen (d > 10) $-        showString "LessThan " . showsPrec 11 (natVal' (proxy# :: Proxy# n))--}+data CompareValue op (sign :: Sign) (n :: Natural) ---type LessThan n = CompareValue LT' n+-- | Precedence of 4 (matching base relational operators e.g. '>=').+instance Predicate (CompareValue op sign n) where+    type PredicateName d (CompareValue op sign n) = ShowParen (d > 4)+        (    "Value " ++ ShowRelOp op ++ ShowChar ' '+          ++ ShowSign sign ++ ShowNatDec n )  instance   ( KnownNat n, Num a, Ord a-  , ReifyRelOp op, ReifySignedNat sign n, ReifySign sign+  , ReifyRelOp op, ReifySignedNat sign n+  , KnownPredicateName (CompareValue op sign n)   ) => Refine (CompareValue op sign n) a where     -- note that we show the reified 'Natural' rather than the coerced numeric     -- type, as otherwise we'd need a @'Show' a@     validate p a =         validateBool p-            ("value not "<>reifyRelOpPretty @op<>" "<>signPretty @sign<>show n)+            ("bad value")             (reifyRelOp @op a (reifySignedNat @sign @n))-      where n = natVal' (proxy# @n)  data Sign = Pos | Neg -class Typeable sign => ReifySign (sign :: Sign) where signPretty :: String-instance ReifySign Pos where signPretty = ""-instance ReifySign Neg where signPretty = "-"+type family ShowSign (sign :: Sign) :: Symbol where+    ShowSign Pos = ""+    ShowSign Neg = "-"  -- TODO do I add any KnownNat constraints anywhere here class ReifySignedNat (sign :: Sign) (n :: Natural) where
src/Rerefined/Predicate/Succeed.hs view
@@ -1,9 +1,10 @@+{-# LANGUAGE OverloadedStrings #-}+ module Rerefined.Predicate.Succeed where  import Rerefined.Predicate.Common  -- | The unit predicate. Always succeeds.-data Succeed deriving Predicate via Typeably Succeed--instance Refine Succeed a where-    validate _ _ = Nothing+data Succeed+instance Predicate Succeed where type PredicateName d Succeed = "⊤"+instance Refine Succeed a where validate _ _ = Nothing
src/Rerefined/Predicates.hs view
@@ -7,14 +7,13 @@   , Fail    -- * Logical-  , Not-  , Logical+  , And, Iff, If, Nand, Nor, Not, Or, Xor    -- * Relational   , CompareValue   , Sign(..)-  , RelOp(..)   , CompareLength+  , LTE, GTE   ) where  import Rerefined.Predicate.Succeed
− src/Rerefined/Predicates/RefinedShim.hs
@@ -1,3 +0,0 @@-module Rerefined.Predicates.RefinedShim where---- TODO cba
src/Rerefined/Refine.hs view
@@ -15,17 +15,19 @@   -- * Errors   , type RefineFailure   , prettyRefineFailure+  , prettyRefineFailure'   ) where  import Rerefined.Refined-import Rerefined.Refined1 import Rerefined.Predicate-import GHC.Exts ( proxy#, IsString )+import GHC.Exts ( proxy# )+import Data.Text ( Text )+import Data.Text.Builder.Linear qualified as TBL  -- | Refine @a@ with predicate @p@. refine     :: forall p a. Refine p a-    => a -> Either (RefineFailure String) (Refined p a)+    => a -> Either RefineFailure (Refined p a) refine a =     case validate (proxy# @p) a of       Nothing -> Right (Refined a)@@ -37,23 +39,48 @@ -- | Refine @f a@ with functor predicate @p@. refine1     :: forall p f a. Refine1 p f-    => f a -> Either (RefineFailure String) (Refined1 p f a)+    => f a -> Either RefineFailure (Refined1 p f a) refine1 fa =     case validate1 (proxy# @p) fa of       Nothing -> Right (Refined1 fa)       Just e  -> Left e --- TODO needs work. boring & idk how to format nicely. and extra \n at start-prettyRefineFailure :: (Semigroup a, IsString a) => RefineFailure a -> a-prettyRefineFailure = go (0 :: Int) . (\e -> [e])+{- TODO+* got an extra \n at start oops+* make it look better lol+* make tail-call recursive? need to ferry more indents around though+-}+prettyRefineFailure :: RefineFailure -> Text+prettyRefineFailure = TBL.runBuilder . go (0 :: Int) . (\e -> [e])   where     go n = \case-      []     -> ""+      []     -> mempty       (e:es) ->-           "\n" <> indent n     <> refineFailurePredicate e-        <> "\n" <> indent (n+2) <> refineFailureDetail    e-        <> go (n+2) (refineFailureInner e)-        <> go n es+        let bPred   = TBL.fromChar '\n' <> indent n <> refineFailurePredicate e+            bDetail = TBL.fromChar '\n' <> indent (n+2) <> refineFailureDetail e+         in bPred <> bDetail <> go (n+2) (refineFailureInner e) <> go n es     indent = \case-      0 -> ""-      n -> " " <> indent (n-1)+      0 -> mempty+      n -> TBL.fromChar ' ' <> indent (n-1)++-- TODO this requires switching inner errors so that last is first lol x)+-- also we only <> right. maybe that's useful for perf+-- to remove newline at start we need to start in a special mode so we know not+-- to add the first newline at bPred. but I cba it will be messier and I want to+-- replace this ASAP when someone comes up with a good pretty error format+prettyRefineFailure' :: RefineFailure -> Text+prettyRefineFailure' = \e -> TBL.runBuilder $ go mempty [(0 :: Int, e)]+  where+    go b = \case+      []            -> b+      ((n, e) : es) ->+        let bPred   = TBL.fromChar '\n' <> indent n <> refineFailurePredicate e+            bDetail = TBL.fromChar '\n' <> indent (n+2) <> refineFailureDetail e+            b'      = b <> bPred <> bDetail+         in go b' (idk (n+2) es (refineFailureInner e))+    indent = \case+      0 -> mempty+      n -> TBL.fromChar ' ' <> indent (n-1)+    idk n rs = \case+      []   -> rs+      l:ls -> idk n ((n, l):rs) ls
src/Rerefined/Refine/TH.hs view
@@ -6,6 +6,7 @@ import Rerefined.Refine import Rerefined.Predicate import Language.Haskell.TH.Syntax qualified as TH+import Data.Text qualified as Text  -- | Refine @a@ with predicate @p@ at compile time via Template Haskell. refineTH@@ -25,5 +26,6 @@ refine1TH = either refineTHFail TH.liftTyped . refine1 @p @f  -- | Template Haskell refinement failure helper.-refineTHFail :: forall a m. MonadFail m => RefineFailure String -> TH.Code m a-refineTHFail = TH.liftCode . fail . prettyRefineFailure+refineTHFail+    :: forall a m. MonadFail m => RefineFailure -> TH.Code m a+refineTHFail = TH.liftCode . fail . Text.unpack . prettyRefineFailure
src/Rerefined/Refine/Unsafe.hs view
@@ -23,7 +23,6 @@   ) where  import Rerefined.Refined-import Rerefined.Refined1  -- | Construct a 'Refined' without validating the predicate @p@. --
src/Rerefined/Refined.hs view
@@ -1,18 +1,48 @@--- | 'Refined' definition.+-- | 'Refined' and 'Refined1' definitions for refined values. ----- Not intended for external use. For unsafe refines, use+-- Not intended for external use. For unsafe refining, use -- 'Rerefined.Refine.Unsafe'. -module Rerefined.Refined where+module Rerefined.Refined+  (+  -- * @Refined@+    Refined(..)+  , unrefine +  -- * @Refined1@+  , Refined1(..)+  , unrefine1+  , squashRefined1+  ) where+ import Language.Haskell.TH.Syntax ( Lift )  -- | @a@ refined with predicate @p@. newtype Refined p a = Refined a-    deriving stock (Lift, Show) -- TODO Show? useful but meh?+    deriving stock (Lift, Show)  -- | Strip the refinement from a 'Refined'. -- -- This is kept as a separate function for prettier @'Show' 'Refined'@ output. unrefine :: Refined p a -> a unrefine (Refined a) = a++-- | @f a@ refined with predicate @p@.+--+-- We may derive legal 'Functor', 'Traversable' instances for this as+-- 'Rerefined.Predicate.Refine1' guarantees that the predicate only applies to+-- the functor structure. That is, you _may_ alter a 'Refined1' without+-- re-asserting its predicate, provided your changes are made without altering+-- the structure/shape of @f@ (e.g. 'fmap', 'traverse').+newtype Refined1 p f a = Refined1 (f a)+    deriving stock (Functor, Foldable, Traversable, Lift, Show)++-- | Strip the refinement from a 'Refined1'.+--+-- This is kept as a separate function for prettier @'Show' 'Refined1'@ output.+unrefine1 :: Refined1 p f a -> f a+unrefine1 (Refined1 fa) = fa++-- | Squash a 'Refined1' into a 'Refined'. Essentially forget the @f@.+squashRefined1 :: Refined1 p f a -> Refined p (f a)+squashRefined1 = Refined . unrefine1
− src/Rerefined/Refined1.hs
@@ -1,18 +0,0 @@--- | 'Refined1' definition.------ Not intended for external use. For unsafe refines, use--- 'Rerefined.Refine.Unsafe'.--module Rerefined.Refined1 where--import Language.Haskell.TH.Syntax ( Lift )---- | @f a@ refined with predicate @p@.-newtype Refined1 p f a = Refined1 (f a)-    deriving stock (Functor, Lift, Show) -- TODO Show? useful but meh?---- | Strip the refinement from a 'Refined1'.------ This is kept as a separate function for prettier @'Show' 'Refined1'@ output.-unrefine1 :: Refined1 p f a -> f a-unrefine1 (Refined1 fa) = fa