predicate-typed 0.7.4.1 → 0.7.4.2
raw patch · 27 files changed
+600/−455 lines, 27 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Predicate.Data.Condition: instance forall k1 (prt :: k1) (n :: GHC.Types.Nat) k2 (p :: k2). GHC.Show.Show (Predicate.Data.Condition.GuardsN prt n p)
- Predicate.Data.Condition: instance forall k1 k2 x a (prt :: k1) (n :: GHC.Types.Nat) (p :: k2). (x GHC.Types.~ [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.Enum: instance forall k1 (t :: k1) k2 (def :: k2). GHC.Show.Show (Predicate.Data.Enum.ToEnumBDef' t def)
- Predicate.Data.Enum: instance forall k1 k2 (def :: k1) (t :: k2) 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)) GHC.Types.~ 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.Extra: data IList
- Predicate.Data.Extra: data IMap p q
- Predicate.Data.Extra: data PartitionsBy p q r
- Predicate.Data.Extra: instance GHC.Show.Show Predicate.Data.Extra.IList
- Predicate.Data.Extra: instance Predicate.Core.P Predicate.Data.Extra.IListT x => Predicate.Core.P Predicate.Data.Extra.IList x
- Predicate.Data.Extra: instance forall k1 (p :: k1) k2 (q :: k2) k3 (r :: k3). GHC.Show.Show (Predicate.Data.Extra.PartitionsBy p q r)
- Predicate.Data.Extra: instance forall k1 (p :: k1) k2 (q :: k2). GHC.Show.Show (Predicate.Data.Extra.IMap p q)
- Predicate.Data.Extra: instance forall k1 k2 (p :: k1) (q :: k2) x. Predicate.Core.P (Predicate.Data.Extra.IMapT p q) x => Predicate.Core.P (Predicate.Data.Extra.IMap p q) x
- Predicate.Data.Extra: instance forall k1 k2 k3 (p :: k1) (q :: k2) (r :: k3) x. Predicate.Core.P (Predicate.Data.Extra.PartitionsByT p q r) x => Predicate.Core.P (Predicate.Data.Extra.PartitionsBy p q r) x
- Predicate.Data.Foldable: instance forall k (f :: * -> *) a (t :: k) x. (GHC.Show.Show (f a), Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Control.Lens.Indexed.FoldableWithIndex (Predicate.Core.PP t x) f, x GHC.Types.~ f a, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Foldable.IToList' t) x
- Predicate.Data.Foldable: instance forall k (t :: k). GHC.Show.Show (Predicate.Data.Foldable.IToList' t)
- Predicate.Data.Foldable: instance forall k1 k2 a (t :: * -> *) (p :: k1) x (n :: k2). (GHC.Show.Show a, GHC.Show.Show (t a), Predicate.Core.PP p x GHC.Types.~ 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.Numeric: instance forall k1 (t :: k1) k2 (n :: k2). GHC.Show.Show (Predicate.Data.Numeric.FromInteger' t n)
- Predicate.Data.Numeric: instance forall k1 (t :: k1) k2 (n :: k2). GHC.Show.Show (Predicate.Data.Numeric.FromIntegral' t n)
- Predicate.Data.Numeric: instance forall k1 k2 (t :: k1) a (n :: k2). (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 :: k1) a (n :: k2). (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.Ordering: data Cmp (o :: OrderingP) p q
- Predicate.Data.Ordering: data CmpI (o :: OrderingP) p q
- Predicate.Data.Ordering: data OrdA
- Predicate.Data.Ordering: data OrdA' p q
- Predicate.Data.Ordering: instance GHC.Show.Show Predicate.Data.Ordering.OrdA
- Predicate.Data.Ordering: instance Predicate.Core.P (Predicate.Data.Ordering.OrdA' Predicate.Core.Id Predicate.Core.Id) x => Predicate.Core.P Predicate.Data.Ordering.OrdA x
- Predicate.Data.Ordering: instance forall k1 (p :: k1) k2 (q :: k2). GHC.Show.Show (Predicate.Data.Ordering.OrdA' p q)
- Predicate.Data.Ordering: instance forall k1 k2 (p :: k1) (q :: k2) x. Predicate.Core.P (Predicate.Data.Ordering.OrdAT' p q) x => Predicate.Core.P (Predicate.Data.Ordering.OrdA' p q) x
- Predicate.Misc: asProxyLeft :: proxy a -> proxy1 a -> proxy a
- Predicate.Misc: asProxyRight :: proxy a -> proxy1 a -> proxy1 a
- Predicate.Util: TT :: !ValP -> !Val a -> !String -> !Forest PE -> TT a
- Predicate.Util: [_ttForest] :: TT a -> !Forest PE
- Predicate.Util: [_ttString] :: TT a -> !String
- Predicate.Util: [_ttValP] :: TT a -> !ValP
- Predicate.Util: [_ttVal] :: TT a -> !Val a
- Predicate.Util: _False :: a ~ Bool => Prism' (Val a) ()
- Predicate.Util: _True :: a ~ Bool => Prism' (Val a) ()
- Predicate.Util: val2P :: Lens' (Val a) ValP
- Predicate.Util: val2PBool :: a ~ Bool => Lens' (Val a) ValP
+ Predicate.Core: evalEither :: forall opts p a. (OptC opts, Show (PP p a), P p a) => a -> Either String (PP p a)
+ Predicate.Core: unsafeEval :: forall opts p a. (HasCallStack, OptC opts, Show (PP p a), P p a) => a -> PP p a
+ Predicate.Data.Condition: instance forall (n :: GHC.Types.Nat) k1 (prt :: k1) k2 (p :: k2). GHC.Show.Show (Predicate.Data.Condition.GuardsN n prt p)
+ Predicate.Data.Condition: instance forall k1 k2 x a (prt :: GHC.Types.Nat) (n :: k1) (p :: k2). (x GHC.Types.~ [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.Enum: instance forall k1 (t :: k1) k2 (def :: k2) k3 (p :: k3). GHC.Show.Show (Predicate.Data.Enum.ToEnumBDef' t def p)
+ Predicate.Data.Enum: instance forall k1 k2 k3 (def :: k1) (t :: k2) a (p :: k3). (Predicate.Core.P def (Data.Proxy.Proxy (Predicate.Core.PP t a)), Predicate.Core.PP def (Data.Proxy.Proxy (Predicate.Core.PP t a)) GHC.Types.~ Predicate.Core.PP t a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Show.Show a, GHC.Enum.Bounded (Predicate.Core.PP t a), GHC.Enum.Enum (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP p a), Predicate.Core.P p a) => Predicate.Core.P (Predicate.Data.Enum.ToEnumBDef' t def p) a
+ Predicate.Data.Foldable: instance forall k1 (t :: k1) k2 (p :: k2). GHC.Show.Show (Predicate.Data.Foldable.IToList' t p)
+ Predicate.Data.Foldable: instance forall k1 k2 (t :: k1) x (f :: * -> *) (p :: k2) a. (Data.Typeable.Internal.Typeable (Predicate.Core.PP t x), GHC.Show.Show (Predicate.Core.PP t x), Control.Lens.Indexed.FoldableWithIndex (Predicate.Core.PP t x) f, Predicate.Core.PP p x GHC.Types.~ f a, Predicate.Core.P p x, GHC.Show.Show x, GHC.Show.Show a) => Predicate.Core.P (Predicate.Data.Foldable.IToList' t p) x
+ Predicate.Data.Foldable: instance forall k1 k2 a (p :: k1) x (t :: * -> *) (n :: k2). (GHC.Show.Show a, Predicate.Core.PP p x GHC.Types.~ 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.List: data IList
+ Predicate.Data.List: data IMap p q
+ Predicate.Data.List: data PartitionsBy p q r
+ Predicate.Data.List: instance GHC.Show.Show Predicate.Data.List.IList
+ Predicate.Data.List: instance Predicate.Core.P Predicate.Data.List.IListT x => Predicate.Core.P Predicate.Data.List.IList x
+ Predicate.Data.List: instance forall k1 (p :: k1) k2 (q :: k2) k3 (r :: k3). GHC.Show.Show (Predicate.Data.List.PartitionsBy p q r)
+ Predicate.Data.List: instance forall k1 (p :: k1) k2 (q :: k2). GHC.Show.Show (Predicate.Data.List.IMap p q)
+ Predicate.Data.List: instance forall k1 k2 (p :: k1) (q :: k2) x. Predicate.Core.P (Predicate.Data.List.IMapT p q) x => Predicate.Core.P (Predicate.Data.List.IMap p q) x
+ Predicate.Data.List: instance forall k1 k2 k3 (p :: k1) (q :: k2) (r :: k3) x. Predicate.Core.P (Predicate.Data.List.PartitionsByT p q r) x => Predicate.Core.P (Predicate.Data.List.PartitionsBy p q r) x
+ Predicate.Data.Numeric: instance forall k1 (t :: k1) k2 (p :: k2). GHC.Show.Show (Predicate.Data.Numeric.FromInteger' t p)
+ Predicate.Data.Numeric: instance forall k1 (t :: k1) k2 (p :: k2). GHC.Show.Show (Predicate.Data.Numeric.FromIntegral' t p)
+ Predicate.Data.Numeric: instance forall k1 k2 (t :: k1) a (p :: k2). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP t a)) => Predicate.Core.P (Predicate.Data.Numeric.FromInteger' t p) a
+ Predicate.Data.Numeric: instance forall k1 k2 (t :: k1) a (p :: k2). (GHC.Num.Num (Predicate.Core.PP t a), GHC.Real.Integral (Predicate.Core.PP p a), Predicate.Core.P p a, GHC.Show.Show (Predicate.Core.PP t a), GHC.Show.Show (Predicate.Core.PP p a)) => Predicate.Core.P (Predicate.Data.Numeric.FromIntegral' t p) a
+ Predicate.Data.Ordering: data Compare
+ Predicate.Data.Ordering: data Comparing p
+ Predicate.Data.Ordering: instance GHC.Show.Show Predicate.Data.Ordering.Compare
+ Predicate.Data.Ordering: instance Predicate.Core.P (Predicate.Data.Ordering.Comparing Predicate.Core.Id) x => Predicate.Core.P Predicate.Data.Ordering.Compare x
+ Predicate.Data.Ordering: instance forall k (p :: k) x. Predicate.Core.P (Predicate.Data.Ordering.ComparingT p) x => Predicate.Core.P (Predicate.Data.Ordering.Comparing p) x
+ Predicate.Data.Ordering: instance forall k (p :: k). GHC.Show.Show (Predicate.Data.Ordering.Comparing p)
+ Predicate.Data.Tuple: data FromITuple
+ Predicate.Data.Tuple: instance GHC.Show.Show Predicate.Data.Tuple.FromITuple
+ Predicate.Data.Tuple: instance Predicate.Misc.FromITupleC x => Predicate.Core.P Predicate.Data.Tuple.FromITuple x
+ Predicate.Misc: class FromITupleC x where {
+ Predicate.Misc: cycle' :: [a] -> [a]
+ Predicate.Misc: fromITupleC :: FromITupleC x => x -> FromITupleP x
+ Predicate.Misc: instance Predicate.Misc.FromITupleC ()
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, ())
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, ()))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, ())))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, ()))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, ())))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, ()))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, ())))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, (h, ()))))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, (h, (i, ())))))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, (h, (i, (j, ()))))))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, (h, (i, (j, (k, ())))))))))))
+ Predicate.Misc: instance Predicate.Misc.FromITupleC (a, (b, (c, (d, (e, (f, (g, (h, (i, (j, (k, (l, ()))))))))))))
- Predicate.Data.Condition: data GuardsN prt (n :: Nat) p
+ Predicate.Data.Condition: data GuardsN (n :: Nat) prt p
- Predicate.Data.Enum: data ToEnumBDef' t def
+ Predicate.Data.Enum: data ToEnumBDef' t def p
- Predicate.Data.Foldable: data IToList' t
+ Predicate.Data.Foldable: data IToList' t p
- Predicate.Data.Numeric: data FromInteger' t n
+ Predicate.Data.Numeric: data FromInteger' t p
- Predicate.Data.Numeric: data FromIntegral' t n
+ Predicate.Data.Numeric: data FromIntegral' t p
- Predicate.Examples.Common: type Ip4op = GuardsN (PrintT "octet %d out of range 0-255 found %d" Id) 4 (0 <..> 255) >> 'True
+ Predicate.Examples.Common: type Ip4op = GuardsN 4 (PrintT "octet %d out of range 0-255 found %d" Id) (0 <..> 255) >> 'True
- Predicate.Refined3: type family MakeR3' opts p
+ Predicate.Refined3: type family MakeR3 p
- Predicate.Util: _Fail :: forall a_atyc. Prism' (Val a_atyc) String
+ Predicate.Util: _Fail :: forall a_auyf. Prism' (Val a_auyf) String
- Predicate.Util: _Val :: forall a_atyc a_audq. Prism (Val a_audq) (Val a_atyc) a_audq a_atyc
+ Predicate.Util: _Val :: forall a_auyf a_avdt. Prism (Val a_avdt) (Val a_auyf) a_avdt a_auyf
- Predicate.Util: ttForest :: forall a_audD. Lens' (TT a_audD) (Forest PE)
+ Predicate.Util: ttForest :: forall a_avdG. Lens' (TT a_avdG) (Forest PE)
- Predicate.Util: ttString :: forall a_audD. Lens' (TT a_audD) String
+ Predicate.Util: ttString :: forall a_avdG. Lens' (TT a_avdG) String
Files
- predicate-typed.cabal +2/−2
- src/Predicate/Core.hs +87/−50
- src/Predicate/Data/Char.hs +1/−1
- src/Predicate/Data/Condition.hs +27/−23
- src/Predicate/Data/Enum.hs +21/−15
- src/Predicate/Data/Extra.hs +9/−73
- src/Predicate/Data/Foldable.hs +29/−17
- src/Predicate/Data/IO.hs +1/−0
- src/Predicate/Data/Lifted.hs +6/−3
- src/Predicate/Data/List.hs +81/−9
- src/Predicate/Data/Numeric.hs +22/−22
- src/Predicate/Data/Ordering.hs +48/−44
- src/Predicate/Data/Proxy.hs +7/−5
- src/Predicate/Data/ReadShow.hs +1/−0
- src/Predicate/Data/Regex.hs +38/−28
- src/Predicate/Data/String.hs +11/−11
- src/Predicate/Data/These.hs +7/−6
- src/Predicate/Data/Tuple.hs +24/−2
- src/Predicate/Examples/Common.hs +1/−1
- src/Predicate/Misc.hs +72/−21
- src/Predicate/Refined.hs +10/−7
- src/Predicate/Refined2.hs +25/−9
- src/Predicate/Refined3.hs +13/−13
- src/Predicate/Refined5.hs +13/−9
- src/Predicate/Util.hs +42/−83
- src/Predicate/Util_TH.hs +1/−0
- test/TestJson.hs +1/−1
predicate-typed.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 27025abbd4f913bb4b084f90b828539a965ba7c0b7b1eaada9454db7c0542abe+-- hash: 1cbf6c9b513c819809aea5c7ba639f8270876d5ac8734ba14595ede9fbbc5a41 name: predicate-typed-version: 0.7.4.1+version: 0.7.4.2 synopsis: Predicates, Refinement types and Dsl description: Please see the README on GitHub at <https://github.com/gbwey/predicate-typed#readme> category: Data
src/Predicate/Core.hs view
@@ -34,11 +34,9 @@ , Pure , Coerce , OneP - - -- ** core class - , P(..) + , Swap - -- ** IO evaluation + -- ** impure evaluation , pan , panv , pa @@ -51,6 +49,7 @@ , pz , run , runs + , unsafeEval -- ** pure evaluation , runP @@ -60,6 +59,7 @@ , evalBoolHide , evalHide , evalQuick + , evalEither -- ** wrap, unwrap , Wrap @@ -115,8 +115,9 @@ , type (&) , DoL - -- ** miscellaneous - , Swap + -- ** core class + , P(..) + ) where import Predicate.Misc import Predicate.Util @@ -136,6 +137,7 @@ import Data.Coerce (Coercible) import Data.Tree.Lens (root) import qualified Text.Regex.PCRE.Heavy as RH +import GHC.Stack (HasCallStack) -- $setup -- >>> :set -XDataKinds -- >>> :set -XTypeApplications @@ -168,9 +170,8 @@ -> a -> m (TT (PP p a)) evalBool p opts = fmap fixTTBool . eval p opts --- evalBool p opts = (over (mapped . ttValBool) id) . eval p opts - +-- | A specialised form of 'eval' that returns the result or the error string on failure evalQuick :: forall opts p i . ( OptC opts , P p i @@ -974,7 +975,7 @@ case oDebug opts of DZero -> pure () _ -> unlessNullM (prtTree opts pp) putStrLn - return (_ttVal pp) + return (pp ^. ttVal) -- | run expression with multiple options in a list -- @@ -1113,7 +1114,7 @@ if anyOf (ttForest . folded . root . peValP) (has _FailP) qq then qq & ttForest %~ (hh pp:) -- we still need pp for context else e - Right q -> mkNodeCopy opts qq (lit3 opts msg0 q "" (topMessageEgregious (_ttString qq))) [hh pp, hh qq] + Right q -> mkNodeCopy opts qq (lit3 opts msg0 q "" (topMessageEgregious (qq ^. ttString))) [hh pp, hh qq] -- | infixl version of 'Predicate.Core.>>' data p >>> q deriving Show @@ -1136,10 +1137,9 @@ topMessageEgregious :: String -> String topMessageEgregious s = - let ret = fromMaybe "" $ (RH.scan topMessageExtractRe s ^? _last . _2 . _last) + let ret = fromMaybe "" (RH.scan topMessageExtractRe s ^? _last . _2 . _last) in '{' : (if null ret then s else ret) <> "}" - topMessageExtractRe :: RH.Regex topMessageExtractRe = [RH.re|^.*\{([^}]+)\}.*?|] @@ -1164,6 +1164,7 @@ d = x ^. _Wrapped' in pure $ mkNode opts (Val d) (show3 opts msg0 d x) [] +-- | similar to 'Wrap' where @t@ points to the type data Wrap' t p deriving Show instance ( Show (PP p x) @@ -1206,7 +1207,6 @@ -- Present Sum {getSum = 25} (Sum {getSum = 13} <> Sum {getSum = 12} = Sum {getSum = 25}) -- Val (Sum {getSum = 25}) -- - data Wrap (t :: Type) p deriving Show type WrapT (t :: Type) p = Wrap' (Hole t) p @@ -1504,6 +1504,14 @@ -- >>> pz @(10 % 4 <..> 40 % 5) 33 -- Val False -- +-- >>> pl @(Negate 7 <..> 20) (-4) +-- True (-7 <= -4 <= 20) +-- Val True +-- +-- >>> pl @(Negate 7 <..> 20) 21 +-- False (21 <= 20) +-- Val False +-- data p <..> q deriving Show infix 4 <..> @@ -1662,20 +1670,6 @@ mkNodeB opts True (msg1 <> " i=" ++ show i ++ " " <> topMessage tt) hhs -- | similar to 'fst' --- --- >>> pz @Fst (10,"Abc") --- Val 10 --- --- >>> pz @Fst (10,"Abc",'x') --- Val 10 --- --- >>> pz @Fst (10,"Abc",'x',False) --- Val 10 --- --- >>> pl @Fst (99,'a',False,1.3) --- Present 99 (Fst 99 | (99,'a',False,1.3)) --- Val 99 --- data L1 p deriving Show instance ( Show (ExtractL1T (PP p x)) @@ -1693,6 +1687,21 @@ let b = extractL1C p in mkNode opts (Val b) (show3 opts msg0 b p) [hh pp] +-- | similar to 'fst' +-- +-- >>> pz @Fst (10,"Abc") +-- Val 10 +-- +-- >>> pz @Fst (10,"Abc",'x') +-- Val 10 +-- +-- >>> pz @Fst (10,"Abc",'x',False) +-- Val 10 +-- +-- >>> pl @Fst (99,'a',False,1.3) +-- Present 99 (Fst 99 | (99,'a',False,1.3)) +-- Val 99 +-- data Fst deriving Show type FstT = L1 Id @@ -1701,17 +1710,6 @@ eval _ = eval (Proxy @FstT) -- | similar to 'snd' --- --- >>> pz @Snd (10,"Abc") --- Val "Abc" --- --- >>> pz @Snd (10,"Abc",True) --- Val "Abc" --- --- >>> pl @Snd (99,'a',False,1.3) --- Present 'a' (Snd 'a' | (99,'a',False,1.3)) --- Val 'a' --- data L2 p deriving Show instance ( Show (ExtractL2T (PP p x)) @@ -1729,6 +1727,18 @@ let b = extractL2C p in mkNode opts (Val b) (show3 opts msg0 b p) [hh pp] +-- | similar to 'snd' +-- +-- >>> pz @Snd (10,"Abc") +-- Val "Abc" +-- +-- >>> pz @Snd (10,"Abc",True) +-- Val "Abc" +-- +-- >>> pl @Snd (99,'a',False,1.3) +-- Present 'a' (Snd 'a' | (99,'a',False,1.3)) +-- Val 'a' +-- data Snd deriving Show type SndT = L2 Id @@ -1738,17 +1748,6 @@ eval _ = eval (Proxy @SndT) -- | similar to 3rd element in a n-tuple --- --- >>> pz @Thd (10,"Abc",133) --- Val 133 --- --- >>> pz @Thd (10,"Abc",133,True) --- Val 133 --- --- >>> pl @Thd (99,'a',False,1.3) --- Present False (Thd False | (99,'a',False,1.3)) --- Val False --- data L3 p deriving Show instance ( Show (ExtractL3T (PP p x)) @@ -1766,6 +1765,18 @@ let b = extractL3C p in mkNode opts (Val b) (show3 opts msg0 b p) [hh pp] +-- | similar to 3rd element in a n-tuple +-- +-- >>> pz @Thd (10,"Abc",133) +-- Val 133 +-- +-- >>> pz @Thd (10,"Abc",133,True) +-- Val 133 +-- +-- >>> pl @Thd (99,'a',False,1.3) +-- Present False (Thd False | (99,'a',False,1.3)) +-- Val False +-- data Thd deriving Show type ThdT = L3 Id @@ -1913,7 +1924,7 @@ case getValueLR NoInline opts msg0 qq [] of Left e -> pure e Right q -> do - case chkSize opts msg0 (toList q) [hh qq] of + case chkSize opts msg0 q [hh qq] of Left e -> pure e Right xs -> do ts <- zipWithM (\i a -> ((i, a),) <$> evalHide @p opts a) [0::Int ..] xs @@ -2527,3 +2538,29 @@ instance P L33T x => P L33 x where type PP L33 x = PP L33T x eval _ = eval (Proxy @L33T) + +-- | for use with TH.Lift in a splice. returns a pure value or fails with a tree +unsafeEval :: forall opts p a + . ( HasCallStack + , OptC opts + , Show (PP p a) + , P p a + ) + => a + -> PP p a +unsafeEval = either (error . ("\n" <>)) id . evalEither @opts @p + +-- | run a type level computation and returns the value or a tree with the error +evalEither :: forall opts p a + . ( OptC opts + , Show (PP p a) + , P p a + ) + => a + -> Either String (PP p a) +evalEither a = + let opts = getOpt @opts + pp = runIdentity $ eval (Proxy @p) opts a + in case pp ^. ttVal of + Val r -> Right r + Fail {} -> Left $ prtTree opts pp
src/Predicate/Data/Char.hs view
@@ -233,7 +233,7 @@ -- True ((>>) True | {True (&*) True}) -- Val True -- --- >>> pz @( '(IsControlAll, IsLatin1All , IsHexDigitAll , IsOctDigitAll , IsDigitAll , IsPunctuationAll , IsSeparatorAll , IsSpaceAll)) "abc134" +-- >>> pz @('(IsControlAll, IsLatin1All , IsHexDigitAll , IsOctDigitAll , IsDigitAll , IsPunctuationAll , IsSeparatorAll , IsSpaceAll)) "abc134" -- Val (False,True,True,False,False,False,False,False) -- -- >>> pl @(SplitAts [1,2,10] Id >> Para '[IsLowerAll, IsDigitAll, IsUpperAll]) "abdefghi"
src/Predicate/Data/Condition.hs view
@@ -292,7 +292,7 @@ Right b -> mkNode opts (Val b) (show3 opts msgbase0 b a) (hh rr : hh pp : verboseList opts qq) Right False -> do ee <- eval (Proxy @e) opts (a, Proxy @(PP q (PP r x))) - pure $ case getValueLR NoInline opts ("Case:otherwise failed" <> nullIf ":" (_ttString ee)) ee [hh rr, hh pp] of + pure $ case getValueLR NoInline opts ("Case:otherwise failed" <> nullIf ":" (ee ^. ttString)) ee [hh rr, hh pp] of Left e -> e Right b -> mkNode opts (Val b) (show3 opts msgbase0 b a) [hh rr, hh pp, hh ee] @@ -529,11 +529,11 @@ 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 + Right ws -> + if n /= length ws then + let msg2 = msg0 <> badLength ws n in pure $ mkNode opts (Fail msg2) "" [] - else evalBool (Proxy @(BoolsImpl (LenT ps) ps)) opts as + else evalBool (Proxy @(BoolsImpl (LenT ps) ps)) opts ws data BoolsImpl (n :: Nat) (os :: [(k,k1)]) deriving Show @@ -630,17 +630,6 @@ type PP (BoolsN prt n p) x = Bool 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] --- Fail "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] --- Fail "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] --- Val [23,59,12] --- data GuardsDetailImpl (ps :: [(k,k1)]) deriving Show instance ( [a] ~ x @@ -656,6 +645,17 @@ in pure $ mkNode opts (Fail msg1) "" [] else eval (Proxy @(GuardsImpl (LenT ps) ps)) opts as +-- | 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] +-- Fail "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] +-- Fail "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] +-- Val [23,59,12] +-- data GuardsDetail prt (ps :: [(k0,k1)]) deriving Show type GuardsDetailT prt (ps :: [(k0,k1)]) = GuardsDetailImpl (ToGuardsDetailT prt ps) @@ -671,26 +671,30 @@ -- | leverages 'RepeatT' for repeating predicates (passthrough method) -- --- >>> pz @(GuardsN (PrintT "id=%d must be between 0 and 255, found %d" Id) 4 (0 <..> 0xff)) [121,33,7,256] +-- >>> pz @(GuardsN 4 (PrintT "id=%d must be between 0 and 255, found %d" Id) (0 <..> 0xff)) [121,33,7,256] -- Fail "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 (0 <..> 0xff)) [121,33,7,44] +-- >>> pz @(GuardsN 4 (PrintT "id=%d must be between 0 and 255, found %d" Id) (0 <..> 0xff)) [121,33,7,44] -- Val [121,33,7,44] -- --- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (0 <..> 0xff)) [1,2,3,4] +-- >>> pl @(GuardsN 4 (PrintT "guard(%d) %d is out of range" Id) (0 <..> 0xff)) [1,2,3,4] -- Present [1,2,3,4] (Guards(4)) -- Val [1,2,3,4] -- --- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (0 <..> 0xff)) [1,2,3,4,5] +-- >>> pl @(GuardsN 4 (PrintT "guard(%d) %d is out of range" Id) (0 <..> 0xff)) [1,2,3,4,5] -- Error Guards:invalid length(5) expected 4 -- Fail "Guards:invalid length(5) expected 4" -- --- >>> pl @(GuardsN (PrintT "guard(%d) %d is out of range" Id) 4 (0 <..> 0xff)) [1,2,3] +-- >>> pl @(GuardsN 4 (PrintT "guard(%d) %d is out of range" Id) (0 <..> 0xff)) [1,2,3] -- Error Guards:invalid length(3) expected 4 -- Fail "Guards:invalid length(3) expected 4" -- -data GuardsN prt (n :: Nat) p deriving Show -type GuardsNT prt (n :: Nat) p = Guards (ToGuardsT prt (RepeatT n p)) +-- >>> pl @(Resplit "\\." >> Map (ReadP Int Id) >> GuardsN 4 (PrintT "invalid pos=%d val=%d" Id) (0 <..> 0xff)) "13.22.44.1231" +-- Error invalid pos=3 val=1231 (Guard(3) 1231 | [13,22,44,1231]) +-- Fail "invalid pos=3 val=1231" +-- +data GuardsN (n :: Nat) prt p deriving Show +type GuardsNT (n :: Nat) prt p = Guards (ToGuardsT prt (RepeatT n p)) instance ( x ~ [a] , P (GuardsNT prt n p) x
src/Predicate/Data/Enum.hs view
@@ -389,27 +389,33 @@ type PP (ToEnum t) x = PP (ToEnumT t) x eval _ = eval (Proxy @(ToEnumT t)) -data ToEnumBDef' t def deriving Show +-- | bounded 'toEnum' function where @t@ refers to location of the type and @p@ the location of the input +data ToEnumBDef' t def p deriving Show instance ( P def (Proxy (PP t a)) , PP def (Proxy (PP t a)) ~ PP t a - , Show a , Show (PP t a) + , Show 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 + , Integral (PP p a) + , P p a + ) => P (ToEnumBDef' t def p) a where + type PP (ToEnumBDef' t def p) 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 NoInline opts msg1 pp [] of - Left e -> e - Right _ -> mkNodeCopy opts pp msg1 [hh pp] - Just n -> pure $ mkNode opts (Val n) (show3 opts msg0 n a) [] + pp <- eval (Proxy @p) opts a + case getValueLR NoInline opts msg0 pp [] of + Left e -> pure e + Right (fromIntegral -> p) -> do + case toEnumMay p of + Nothing -> do + let msg1 = msg0 <> " out of range" + dd <- eval (Proxy @def) opts (Proxy @(PP t a)) + pure $ case getValueLR NoInline opts msg1 dd [hh pp] of + Left e -> e + Right _ -> mkNodeCopy opts dd msg1 [hh pp, hh dd] + Just n -> pure $ mkNode opts (Val n) (show3 opts msg0 n a) [hh pp] -- | bounded 'toEnum' function -- @@ -428,7 +434,7 @@ -- Val EQ -- data ToEnumBDef (t :: Type) def deriving Show -type ToEnumBDefT (t :: Type) def = ToEnumBDef' (Hole t) def +type ToEnumBDefT (t :: Type) def = ToEnumBDef' (Hole t) def Id instance P (ToEnumBDefT t def) x => P (ToEnumBDef t def) x where type PP (ToEnumBDef t def) x = PP (ToEnumBDefT t def) x @@ -448,7 +454,7 @@ -- Fail "ToEnum bounded" -- data ToEnumBFail (t :: Type) deriving Show -type ToEnumBFailT (t :: Type) = ToEnumBDef' (Hole t) (FailP "ToEnum bounded") +type ToEnumBFailT (t :: Type) = ToEnumBDef' (Hole t) (FailP "ToEnum bounded") Id instance P (ToEnumBFailT t) x => P (ToEnumBFail t) x where type PP (ToEnumBFail t) x = PP (ToEnumBFailT t) x
src/Predicate/Data/Extra.hs view
@@ -20,22 +20,17 @@ -- ** list functions HeadDef , HeadFail + , HeadMay , TailDef , TailFail + , TailMay , LastDef , LastFail + , LastMay , InitDef , InitFail - - , HeadMay - , LastMay - , TailMay , InitMay - , PartitionsBy - , IMap - , IList - -- ** primes , IsPrime , PrimeNext @@ -50,13 +45,11 @@ import Predicate.Core import Predicate.Misc import Predicate.Util -import Predicate.Data.List (Head, Uncons, Unsnoc, SortBy, Zip, GroupBy, SortOn, ZipWith) -import Predicate.Data.Enum (type (...)) -import Predicate.Data.Numeric (type (-)) +import Predicate.Data.List (Uncons, Unsnoc) import Predicate.Data.Maybe (JustDef, JustFail) import Predicate.Data.Lifted (FMap) import Control.Lens -import qualified Safe (headNote, cycleNote) +import qualified Safe (headNote) import Data.Proxy (Proxy(..)) -- $setup -- >>> :set -XDataKinds @@ -482,68 +475,11 @@ let msg0 = "IsLuhn" in pure $ case chkSize opts msg0 x [] of Left e -> e - Right _ -> - let xs = zipWith (*) (reverse x) (Safe.cycleNote msg0 [1,2]) + Right ws -> + let xs = zipWith (*) (ws ^. reversed) (cycle' [1,2]) ys = map (\w -> if w>=10 then w-9 else w) xs z = sum' ys ret = z `mod` 10 - in if ret == 0 then mkNodeB opts True (msg0 <> " | " <> showL opts x) [] - else mkNodeB opts False (msg0 <> " map=" <> showL opts ys <> " sum=" <> showL opts z <> " ret=" <> showL opts ret <> showVerbose opts " | " x) [] - --- | experimental: sorts then partitions and then sorts each partitions based on the leftmost occurring value in the original list --- if the existing order of data is fine then use 'Predicate.Data.List.GroupBy' as you do not need this --- --- >>> pz @(PartitionsBy (Fst ==! Snd) (L11 == L21) Id) [10,9,9,1,9] --- Val [[10],[9,9,9],[1]] --- --- >>> pz @(PartitionsBy OrdA (L11 < L21) Id) "efaffabec" --- Val ["a","f","f","abce","ef"] --- --- >>> pz @(PartitionsBy 'GT 'True Id) "efaffabec" --- Val ["cebaffafe"] --- --- >>> pz @(PartitionsBy 'GT 'False Id) "efaffabec" --- Val ["e","f","a","f","f","a","b","e","c"] --- --- >>> pz @(PartitionsBy (Fst ==! Snd) (L12 > L22) Id) [10,9,9,1,9,4] --- Val [[9],[1],[9,10],[4,9]] --- --- >>> pz @(PartitionsBy (L11 ==! L21) (L12 > L22) Id) "eddadc" --- Val ["d","a","de","cd"] --- --- >>> pz @(PartitionsBy (L11 ==! L21) (L11 < L21) Id) [10,9,9,1,9,4] --- Val [[9],[1,4,9],[9,10]] --- -data PartitionsBy p q r deriving Show -type PartitionsByT p q r = SortBy p (Zip r (0 ... (Length r - 1))) >> GroupBy q Id >> SortOn (Head >> Snd) Id >> Map (Map Fst) - -instance P (PartitionsByT p q r) x => P (PartitionsBy p q r) x where - type PP (PartitionsBy p q r) x = PP (PartitionsByT p q r) x - eval _ = eval (Proxy @(PartitionsByT p q r)) - --- | add an index to map --- --- >>> pz @(Rescan "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" >> Map (Snd >> IMap (GuardBool (PrintT "bad value=%d %s" Id) (Snd >> ReadP Int Id < 255)) Id)) "123.222.999.3" --- Fail "bad value=2 999" --- --- >>> pz @(Rescan "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" >> Map (Snd >> IMap (GuardBool (PrintT "bad value=%d %s" Id) (Snd >> ReadP Int Id < 255)) Id)) "123.222.99.3" --- Val [[True,True,True,True]] --- -data IMap p q deriving Show -type IMapT p q = ZipWith p (0 ... (Length q - 1)) q - -instance P (IMapT p q) x => P (IMap p q) x where - type PP (IMap p q) x = PP (IMapT p q) x - eval _ = eval (Proxy @(IMapT p q)) - --- | add an index to list --- --- >>> pz @IList "abcdef" --- Val [(0,'a'),(1,'b'),(2,'c'),(3,'d'),(4,'e'),(5,'f')] --- -data IList deriving Show -type IListT = Zip (0 ... (Len - 1)) Id + in if ret == 0 then mkNodeB opts True (msg0 <> " | " <> showL opts ws) [] + else mkNodeB opts False (msg0 <> " map=" <> showL opts ys <> " sum=" <> showL opts z <> " ret=" <> showL opts ret <> showVerbose opts " | " ws) [] -instance P IListT x => P IList x where - type PP IList x = PP IListT x - eval _ = eval (Proxy @IListT)
src/Predicate/Data/Foldable.hs view
@@ -53,7 +53,6 @@ import Data.List.NonEmpty (NonEmpty(..)) import qualified GHC.Exts as GE import Data.List (findIndex) -import qualified Safe (cycleNote) -- $setup -- >>> import Predicate.Prelude -- >>> :set -XDataKinds @@ -124,21 +123,31 @@ let b = has _Empty as in pure $ mkNodeB opts b ("IsEmpty" <> showVerbose opts " | " as) [] -data IToList' t deriving Show +-- | explicit version of 'IToList' with an extra parameter @p@ to point to the value +-- +-- >>> pz @(IToList' (Hole _) Snd) (True,"aBc" :: String) +-- Val [(0,'a'),(1,'B'),(2,'c')] +-- +data IToList' t p deriving Show -instance ( Show (f a) - , Typeable (PP t x) +instance ( Typeable (PP t x) , Show (PP t x) , FoldableWithIndex (PP t x) f - , x ~ f a + , PP p x ~ f a + , P p x + , Show x , Show a - ) => P (IToList' t) x where - type PP (IToList' t) x = [(PP t x, ExtractAFromTA x)] - eval _ opts x = + ) => P (IToList' t p) x where + type PP (IToList' t p) x = [(PP t x, ExtractAFromTA (PP p x))] + eval _ opts x = do let msg0 = "IToList" - b = itoList x t = showT @(PP t x) - in pure $ mkNode opts (Val b) (msg0 <> "(" <> t <> ") " <> showL opts b <> showVerbose opts " | " x) [] + pp <- eval (Proxy @p) opts x + pure $ case getValueLR NoInline opts msg0 pp [] of + Left e -> e + Right p -> + let b = itoList p + in mkNode opts (Val b) (msg0 <> "(" <> t <> ") " <> showL opts b <> showVerbose opts " | " x) [hh pp] -- | similar to 'Control.Lens.itoList' -- @@ -178,7 +187,7 @@ -- Val [(0,'a'),(1,'b'),(2,'c')] -- data IToList (t :: Type) deriving Show -type IToListT (t :: Type) = IToList' (Hole t) +type IToListT (t :: Type) = IToList' (Hole t) Id instance P (IToListT t) x => P (IToList t) x where type PP (IToList t) x = PP (IToListT t) x @@ -261,7 +270,7 @@ -- >>> pz @Concat ["abc","D","eF","","G"] -- Val "abcDeFG" -- --- >>> pz @(Lift Concat Snd) ('x',["abc","D","eF","","G"]) +-- >>> pz @(Snd >> Concat) ('x',["abc","D","eF","","G"]) -- Val "abcDeFG" -- data Concat deriving Show @@ -286,15 +295,17 @@ eval _ = eval (Proxy @(ConcatMapT p q)) --- | similar to 'cycle' but for a fixed number @n@ +-- | similar to 'cycle' but for a fixed number @n@: for an empty list it just returns an empty list -- -- >>> pz @(Cycle 5 Id) [1,2] -- Val [1,2,1,2,1] -- +-- >>> pz @(Cycle 5 Id) [] +-- Val [] +-- data Cycle n p deriving Show instance ( Show a - , Show (t a) , PP p x ~ t a , P p x , Integral (PP n x) @@ -311,10 +322,10 @@ let hhs = [hh nn, hh pp] in case chkSize opts msg0 p hhs of Left e -> e - Right _ -> + Right ps -> let msg1 = msg0 <> "(" <> show n <> ")" - d = take n (Safe.cycleNote msg0 (toList p)) - in mkNode opts (Val d) (show3 opts msg1 d p) hhs + d = take n (cycle' ps) + in mkNode opts (Val d) (show3 opts msg1 d ps) hhs -- | similar to 'toList' @@ -356,6 +367,7 @@ z = toList as in pure $ mkNode opts (Val z) (msg0 <> showVerbose opts " " as) [] +-- | explicit version of 'Null' with an extra parameter @p@ to point to the value data Null' p deriving Show instance ( Show (t a)
src/Predicate/Data/IO.hs view
@@ -323,6 +323,7 @@ -- | 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" +-- | similar to 'ReadIO' but allow the user to specify the prompt string @s@ type ReadIO' (t :: Type) s = Stdout (s <> ":") >> Stdin >> ReadP t Id -- eg pa @(ReadIO Int + ReadIO Int) ()
src/Predicate/Data/Lifted.hs view
@@ -658,6 +658,9 @@ type PP (K p q) a = PP p a eval _ = eval (Proxy @(MsgI "K " p)) +-- useful only when you need an extra arg function or p is a constant or p and Id can be the same +-- also useful if you dont want to have parens cos of >> +-- Lift Rescan Fst wont work as Id and Fst are different: how can regex pattern be the same as the value you are matching against! -- | Lift a no arg Adt to a function of one argument (for use with 'Dot' and 'RDot') -- -- >>> pl @(Lift Len Snd) (True,"abcdef") @@ -989,7 +992,7 @@ -- >>> pz @((1 ... 10) >>= EmptyBool [] Even '[Id,Id]) () -- Val [[2,2],[4,4],[6,6],[8,8],[10,10]] -- --- >>> pz @( (1 ... 10) >>= If Even '[Id,Id] (EmptyT [])) () +-- >>> pz @((1 ... 10) >>= If Even '[Id,Id] (EmptyT [])) () -- Val [2,2,4,4,6,6,8,8,10,10] -- -- >>> pz @(Lookup 0 Id >>= Lookup 1 Id) [[1,2,3]] @@ -1068,10 +1071,10 @@ -- >>> pz @(Flip Map' Id Succ) [1..5] -- Val [2,3,4,5,6] -- --- >>> pz @( Flip '(,) 'True 2) () +-- >>> pz @(Flip '(,) 'True 2) () -- Val (2,True) -- --- >>> pz @( Flip ('(,,) 1) 2 Id) "ab" +-- >>> pz @(Flip ('(,,) 1) 2 Id) "ab" -- Val (1,"ab",2) -- data Flip (p :: k1 -> k2 -> k3) (q :: k2) (r :: k1) deriving Show
src/Predicate/Data/List.hs view
@@ -66,6 +66,9 @@ , Break , Span , Intercalate + , PartitionsBy + , IMap + , IList -- ** miscellaneous , Elem @@ -100,8 +103,9 @@ import Predicate.Core import Predicate.Misc import Predicate.Util -import Predicate.Data.Ordering (type (==), OrdA', type (>)) -import Predicate.Data.Numeric (Mod) +import Predicate.Data.Ordering (type (==), Comparing, type (>)) +import Predicate.Data.Numeric (Mod, type (-)) +import Predicate.Data.Enum (type (...)) import Predicate.Data.Monoid (type (<>)) import Control.Lens import Data.List (foldl', partition, intercalate, inits, tails, unfoldr, sortOn) @@ -175,7 +179,7 @@ -- >>> pz @(123 :+ EmptyList _) "somestuff" -- Val [123] -- --- >>> pl @(FlipT (:+) Fst Snd) ([1..5],99) +-- >>> pl @(Flip (:+) Fst Snd) ([1..5],99) -- Present [99,1,2,3,4,5] ((:+) [99,1,2,3,4,5] | p=99 | q=[1,2,3,4,5]) -- Val [99,1,2,3,4,5] -- @@ -191,7 +195,7 @@ -- Present [4,1,2,3] ((:+) [4,1,2,3] | p=4 | q=[1,2,3]) -- Val [4,1,2,3] -- --- >>> pl @(FlipT (:+) '[1,2,3] 5) () +-- >>> pl @(Flip (:+) '[1,2,3] 5) () -- Present [5,1,2,3] ((:+) [5,1,2,3] | p=5 | q=[1,2,3]) -- Val [5,1,2,3] -- @@ -1415,11 +1419,11 @@ -- >>> pz @(SortBy ((L11 ==! L21) <> (L22 ==! L12)) Id) [(10,"ab"),(4,"x"),(20,"bbb"),(4,"a"),(4,"y")] -- Val [(4,"y"),(4,"x"),(4,"a"),(10,"ab"),(20,"bbb")] -- --- >>> pl @(SortBy (Swap >> OrdA' Fst Fst) Snd) ((),[('z',1),('a',10),('m',22)]) +-- >>> pl @(SortBy (Swap >> Comparing Fst) Snd) ((),[('z',1),('a',10),('m',22)]) -- Present [('z',1),('m',22),('a',10)] (SortBy [('z',1),('m',22),('a',10)]) -- Val [('z',1),('m',22),('a',10)] -- --- >>> pl @(SortBy (OrdA' Reverse Reverse) Id) ["az","by","cx","aa"] +-- >>> pl @(SortBy (Comparing Reverse) Id) ["az","by","cx","aa"] -- Present ["aa","cx","by","az"] (SortBy ["aa","cx","by","az"]) -- Val ["aa","cx","by","az"] -- @@ -1427,7 +1431,7 @@ -- Error pivot=5 value=3(2) (Partition(i=1, a=(5,3)) excnt=2 | SortBy) -- Fail "pivot=5 value=3(2)" -- --- >>> pl @(SortBy (If (Fst==50 && Snd==3) (FailT _ (PrintT "pivot=%d value=%d" Id)) OrdA) Snd) ((), [5,7,3,1,6,2,1,3]) +-- >>> pl @(SortBy (If (Fst==50 && Snd==3) (FailT _ (PrintT "pivot=%d value=%d" Id)) Compare) Snd) ((), [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]) -- Val [1,1,2,3,3,5,6,7] -- @@ -1511,7 +1515,7 @@ -- Val [('a',9),('a',10),('m',10),('m',22),('z',1)] -- data SortOn p q deriving Show -type SortOnT p q = SortBy (OrdA' p p) q +type SortOnT p q = SortBy (Comparing 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 @@ -1528,7 +1532,7 @@ -- Val [('z',1),('m',22),('a',10)] -- data SortOnDesc p q deriving Show -type SortOnDescT p q = SortBy (Swap >> OrdA' p p) q +type SortOnDescT p q = SortBy (Swap >> Comparing 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 @@ -1606,6 +1610,7 @@ Left e -> e Right p -> mkNode opts (Val [p]) msg0 [hh pp] +-- | creates an empty list for the given pointer to a type @t@ data EmptyList' t deriving Show instance P (EmptyList' t) x where @@ -2142,3 +2147,70 @@ Right _ -> let d = liftA2 (,) p q in mkNode opts (Val d) (show3' opts msg0 d "p=" p <> showVerbose opts " | q=" q) hhs + +-- | experimental: sorts then partitions and then sorts each partitions based on the leftmost occurring value in the original list +-- if the existing order of data is fine then use 'Predicate.Data.List.GroupBy' as you do not need this +-- +-- >>> pz @(PartitionsBy (Fst ==! Snd) (L11 == L21) Id) [10,9,9,1,9] +-- Val [[10],[9,9,9],[1]] +-- +-- >>> pz @(PartitionsBy Compare (L11 < L21) Id) "efaffabec" +-- Val ["a","f","f","abce","ef"] +-- +-- >>> pz @(PartitionsBy 'GT 'True Id) "efaffabec" +-- Val ["cebaffafe"] +-- +-- >>> pz @(PartitionsBy 'GT 'False Id) "efaffabec" +-- Val ["e","f","a","f","f","a","b","e","c"] +-- +-- >>> pz @(PartitionsBy (Fst ==! Snd) (L12 > L22) Id) [10,9,9,1,9,4] +-- Val [[9],[1],[9,10],[4,9]] +-- +-- >>> pz @(PartitionsBy (L11 ==! L21) (L12 > L22) Id) "eddadc" +-- Val ["d","a","de","cd"] +-- +-- >>> pz @(PartitionsBy (L11 ==! L21) (L11 < L21) Id) [10,9,9,1,9,4] +-- Val [[9],[1,4,9],[9,10]] +-- +data PartitionsBy p q r deriving Show +type PartitionsByT p q r = SortBy p (Zip r (0 ... (Length r - 1))) >> GroupBy q Id >> SortOn (Head >> Snd) Id >> Map (Map Fst) + +instance P (PartitionsByT p q r) x => P (PartitionsBy p q r) x where + type PP (PartitionsBy p q r) x = PP (PartitionsByT p q r) x + eval _ = eval (Proxy @(PartitionsByT p q r)) + +-- | add an index to map +-- +-- >>> pz @(IMap (Second Succ) Id) "hello" +-- Val [(0,'i'),(1,'f'),(2,'m'),(3,'m'),(4,'p')] +-- +-- >>> pz @(IMap (10 ^ Fst * Snd) Id >> Sum) [3,2,7,9] +-- Val 9723 +-- +-- >>> pz @(IMap (2 ^ Fst * Snd) Id) [1,1,1,0,1,0,1] +-- Val [1,2,4,0,16,0,64] +-- +-- >>> pz @(Rescan "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" >> Map (Snd >> IMap (GuardBool (PrintT "bad value=%d %s" Id) (Snd >> ReadP Int Id < 255)) Id)) "123.222.999.3" +-- Fail "bad value=2 999" +-- +-- >>> pz @(Rescan "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$" >> Map (Snd >> IMap (GuardBool (PrintT "bad value=%d %s" Id) (Snd >> ReadP Int Id < 255)) Id)) "123.222.99.3" +-- Val [[True,True,True,True]] +-- +data IMap p q deriving Show +type IMapT p q = ZipWith p (0 ... (Length q - 1)) q + +instance P (IMapT p q) x => P (IMap p q) x where + type PP (IMap p q) x = PP (IMapT p q) x + eval _ = eval (Proxy @(IMapT p q)) + +-- | add an index to list +-- +-- >>> pz @IList "abcdef" +-- Val [(0,'a'),(1,'b'),(2,'c'),(3,'d'),(4,'e'),(5,'f')] +-- +data IList deriving Show +type IListT = Zip (0 ... (Len - 1)) Id + +instance P IListT x => P IList x where + type PP IList x = PP IListT x + eval _ = eval (Proxy @IListT)
src/Predicate/Data/Numeric.hs view
@@ -92,22 +92,22 @@ -- >>> import Data.Time -- | 'fromInteger' function where you need to provide a reference to the type @t@ of the result -data FromInteger' t n deriving Show +data FromInteger' t p deriving Show instance ( Num (PP t a) - , Integral (PP n a) - , P n a + , Integral (PP p a) + , P p a , Show (PP t a) - ) => P (FromInteger' t n) a where - type PP (FromInteger' t n) a = PP t a + ) => P (FromInteger' t p) a where + type PP (FromInteger' t p) a = PP t a eval _ opts a = do let msg0 = "FromInteger" - nn <- eval (Proxy @n) opts a - pure $ case getValueLR NoInline opts msg0 nn [] of + pp <- eval (Proxy @p) opts a + pure $ case getValueLR NoInline opts msg0 pp [] of Left e -> e - Right n -> - let b = fromInteger (fromIntegral n) - in mkNode opts (Val b) (msg0 <> " " <> showL opts b) [hh nn] + Right p -> + let b = fromInteger (fromIntegral p) + in mkNode opts (Val b) (msg0 <> " " <> showL opts b) [hh pp] -- | 'fromInteger' function where you need to provide the type @t@ of the result -- @@ -138,30 +138,30 @@ -- data FromInteger (t :: Type) deriving Show type FromIntegerT (t :: Type) = FromInteger' (Hole t) Id ---type FromIntegerP n = FromInteger' UnproxyT n +--type FromIntegerP p = FromInteger' UnproxyT n instance P (FromIntegerT t) x => P (FromInteger t) x where type PP (FromInteger t) x = PP (FromIntegerT t) x eval _ = eval (Proxy @(FromIntegerT t)) -- | 'fromIntegral' function where you need to provide a reference to the type @t@ of the result -data FromIntegral' t n deriving Show +data FromIntegral' t p deriving Show instance ( Num (PP t a) - , Integral (PP n a) - , P n a + , Integral (PP p a) + , P p a , Show (PP t a) - , Show (PP n a) - ) => P (FromIntegral' t n) a where - type PP (FromIntegral' t n) a = PP t a + , Show (PP p a) + ) => P (FromIntegral' t p) a where + type PP (FromIntegral' t p) a = PP t a eval _ opts a = do let msg0 = "FromIntegral" - nn <- eval (Proxy @n) opts a - pure $ case getValueLR NoInline opts msg0 nn [] of + pp <- eval (Proxy @p) opts a + pure $ case getValueLR NoInline opts msg0 pp [] of Left e -> e - Right n -> - let b = fromIntegral n - in mkNode opts (Val b) (show3 opts msg0 b n) [hh nn] + Right p -> + let b = fromIntegral p + in mkNode opts (Val b) (show3 opts msg0 b p) [hh pp] -- | 'fromIntegral' function where you need to provide the type @t@ of the result --
src/Predicate/Data/Ordering.hs view
@@ -35,11 +35,9 @@ , Lt , Ne , type (==!) - , OrdA' - , OrdA + , Comparing + , Compare , type (===~) - , Cmp - , CmpI , Asc , Asc' , Desc @@ -103,6 +101,15 @@ eval _ = eval (Proxy @(LeT n)) -- | compare if expression @p@ is less than to @q@ +-- +-- >>> pl @(Lt 4) 123 +-- False (123 < 4) +-- Val False +-- +-- >>> pl @(Lt 4) 1 +-- True (1 < 4) +-- Val True +-- data Lt n deriving Show type LtT n = Id < n @@ -243,6 +250,19 @@ eval _ = evalBool (Proxy @(CmpI 'CGe p q)) -- | case-insensitive compare if string expression @p@ is equal to @q@ +-- +-- >>> pl @("Abc" ==~ Id) "abc" +-- True (Abc ==~ abc) +-- Val True +-- +-- >>> pl @(Fst ==~ Snd) ("aBc","AbC") +-- True (aBc ==~ AbC) +-- Val True +-- +-- >>> pl @(Fst ==~ Snd && Fst == Snd) ("Abc","Abc") +-- True (True && True) +-- Val True +-- data p ==~ q deriving Show infix 4 ==~ @@ -336,19 +356,33 @@ let d = compare p q in mkNode opts (Val 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 deriving Show +-- | similar to 'compare' for a tuple +-- +-- >>> pl @Compare ('b','A') +-- Present GT ((==!) 'b' > 'A') +-- Val GT +-- +-- >>> pl @(Compare) (13,99) +-- Present LT ((==!) 13 < 99) +-- Val LT +-- +data Compare deriving Show -instance P (OrdA' Id Id) x => P OrdA x where - type PP OrdA x = PP (OrdA' Id Id) x - eval _ = eval (Proxy @(OrdA' Id Id)) +instance P (Comparing Id) x => P Compare x where + type PP Compare x = PP (Comparing Id) x + eval _ = eval (Proxy @(Comparing Id)) -data OrdA' p q deriving Show -type OrdAT' p q = (Fst >> p) ==! (Snd >> q) +-- | similar to 'Data.Ord.comparing' for a tuple +-- +-- >>> pz @(Comparing Len) ("abc","123456") +-- Val LT +-- +data Comparing p deriving Show +type ComparingT p = (Fst >> p) ==! (Snd >> p) -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)) +instance P (ComparingT p) x => P (Comparing p) x where + type PP (Comparing p) x = PP (ComparingT p) x + eval _ = eval (Proxy @(ComparingT p)) -- | compare two strings ignoring case and return an ordering -- @@ -371,19 +405,6 @@ -- Present EQ ((===~) Abc = abc) -- Val EQ -- --- --- >>> pl @("Abc" ==~ Id) "abc" --- True (Abc ==~ abc) --- Val True --- --- >>> pl @(Fst ==~ Snd) ("aBc","AbC") --- True (aBc ==~ AbC) --- Val True --- --- >>> pl @(Fst ==~ Snd && Fst == Snd) ("Abc","Abc") --- True (True && True) --- Val True --- data p ===~ q deriving Show infix 4 ===~ @@ -403,23 +424,6 @@ in mkNode opts (Val 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) --- Val False --- --- >>> pl @(Lt 4) 1 --- True (1 < 4) --- Val True --- --- >>> pl @(Negate 7 <..> 20) (-4) --- True (-7 <= -4 <= 20) --- Val True --- --- >>> pl @(Negate 7 <..> 20) 21 --- False (21 <= 20) --- Val False --- data Cmp (o :: OrderingP) p q deriving Show instance ( GetOrd o
src/Predicate/Data/Proxy.hs view
@@ -38,6 +38,7 @@ import qualified GHC.TypeLits as GL import Data.Kind (Type) import Data.Typeable (Proxy(..)) +import Control.Lens -- $setup -- >>> :set -XDataKinds -- >>> :set -XTypeApplications @@ -195,7 +196,7 @@ zz <- eval (Proxy @z) opts q pure $ case getValueLR NoInline opts msg0 zz [hh qq] of Left e -> e - Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (_ttString zz)) [hh qq,hh zz] + Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (zz ^. ttString)) [hh qq,hh zz] -- the key is to pass all the vars into the type family so ghc can figure stuff out type family Pop0T (p :: Type) (q :: Type) :: Type where @@ -238,6 +239,7 @@ -- -- >>> pz @(Pop1 (Proxy ('(,) 'True)) Len "abc") () -- Val (True,3) +-- data Pop1 p q r deriving Show instance ( P r x @@ -255,7 +257,7 @@ zz <- eval (Proxy @(z q)) opts r pure $ case getValueLR NoInline opts msg0 zz [hh rr] of Left e -> e - Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (_ttString zz)) [hh rr,hh zz] + Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (zz ^. ttString)) [hh rr,hh zz] type family Pop1T (p :: Type) (q :: k) (r :: Type) :: Type where Pop1T (Proxy z) q r = PP (z q) r @@ -317,7 +319,7 @@ zz <- eval (Proxy @(z w)) opts r pure $ case getValueLR NoInline opts msg0 zz [hh rr] of Left e -> e - Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (_ttString zz)) [hh rr,hh zz] + Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (zz ^. ttString)) [hh rr,hh zz] type family Pop1'T (p :: Type) (q :: Type) (r :: Type) :: Type where Pop1'T (Proxy z) (Proxy w) r = PP (z w) r @@ -354,7 +356,7 @@ zz <- eval (Proxy @(z q r)) opts s pure $ case getValueLR NoInline opts msg0 zz [hh ss] of Left e -> e - Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (_ttString zz)) [hh ss,hh zz] + Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (zz ^. ttString)) [hh ss,hh zz] -- pass all the arguments in!!! else ghc gets confused type family Pop2T (p :: Type) (q :: k) (r :: k1) (s :: Type) :: Type where @@ -398,7 +400,7 @@ zz <- eval (Proxy @(z w v)) opts s pure $ case getValueLR NoInline opts msg0 zz [hh ss] of Left e -> e - Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (_ttString zz)) [hh ss,hh zz] + Right _z -> mkNodeCopy opts zz (msg0 <> nullIf " | " (zz ^. ttString)) [hh ss,hh zz] -- pass in all the arguments otherwise ghc gets confused type family Pop2'T (p :: Type) (q :: Type) (r :: Type) (s :: Type) :: Type where
src/Predicate/Data/ReadShow.hs view
@@ -133,6 +133,7 @@ type PP (ReadP t p) x = PP (ReadPT t p) x eval _ = eval (Proxy @(ReadPT t p)) +-- | same as 'ReadMaybe' except @t@ is a pointer to the type data ReadMaybe' t p deriving Show instance ( P p x
src/Predicate/Data/Regex.hs view
@@ -175,6 +175,12 @@ -- >>> pz @(Rescan' '[] Snd "13:05:25") ('a',"^(\\d{2}):(\\d{2}):(\\d{2})$") -- Val [("13:05:25",["13","05","25"])] -- +-- >>> pz @('(Id,Intercalate '["\\."] (Repeat 4 "([01]?\\d?\\d|2[0-4]\\d|25[0-5])") >> Concat) >> Rescan' '[] ("^" <> Snd <> "$") Fst) "1.2.3.255" -- have to use Rescan' here: Lift helps not! +-- Val [("1.2.3.255",["1","2","3","255"])] +-- +-- >>> pz @('(Id,Intercalate '["\\."] (Repeat 4 "([01]?\\d?\\d|2[0-4]\\d|25[0-5])") >> Concat) >> Rescan' '[] ("^" <> Snd <> "$") Fst >> FMap (Second (FMap (ReadP Int Id)))) "1.2.3.255" +-- Val [("1.2.3.255",[1,2,3,255])] +-- data Rescan' (rs :: [ROpt]) p q deriving Show instance ( GetROpts rs @@ -258,6 +264,9 @@ -- Present [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])] (Rescan (([[:xdigit:]]{2})) [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])] | wfeb12az) -- Val [("fe",["fe"]),("b1",["b1"]),("2a",["2a"])] -- +-- >>> pz @(Rescan "^Date\\((\\d+)(\\d{3}[+-]\\d{4})\\)" >> Head >> Snd >> (Id !! 0 <> "." <> Id !! 1) >> ParseTimeP ZonedTime "%s%Q%z") "Date(1593460089052+0800)" +-- Val 2020-06-30 03:48:09.052 +0800 +-- data Rescan p deriving Show type RescanT p = Rescan' '[] p Id @@ -265,7 +274,7 @@ type PP (Rescan p) x = PP (RescanT p) x eval _ = eval (Proxy @(RescanT p)) - +-- | similar to 'RescanRanges' but also allows the regex options @rs@ to be specified data RescanRanges' (rs :: [ROpt]) p q deriving Show instance ( GetROpts rs @@ -369,11 +378,6 @@ type PP (Resplit p) x = PP (ResplitT p) x eval _ = eval (Proxy @(ResplitT p)) --- | replaces regex @s@ with a string @s1@ inside the value: see 'RH.sub' and 'RH.gsub' --- --- >>> pz @(ReplaceAllString 'ROverWrite "\\." ":" Id) "141.201.1.22" --- Val "141:201:1:22" --- data ReplaceImpl (alle :: Bool) (rs :: [ROpt]) p q r deriving Show instance ( GetBool b @@ -416,6 +420,7 @@ RReplace3 s -> (if alle then RH.gsub else RH.sub) regex s r in mkNode opts (Val ret) (msg1 <> " " <> litL opts r <> litVerbose opts " | " ret) (hhs <> [hh rr]) +-- | replaces all values using regex @p@ with a replacement function @q@ inside the value @r@ using regex options @rs@ data ReplaceAll' (rs :: [ROpt]) p q r deriving Show type ReplaceAllT' (rs :: [ROpt]) p q r = ReplaceImpl 'True rs p q r @@ -423,6 +428,7 @@ type PP (ReplaceAll' rs p q r) x = PP (ReplaceAllT' rs p q r) x eval _ = eval (Proxy @(ReplaceAllT' rs p q r)) +-- | replaces all values using regex @p@ with a replacement function @q@ inside the value @r@ data ReplaceAll p q r deriving Show type ReplaceAllT p q r = ReplaceAll' '[] p q r @@ -430,6 +436,7 @@ type PP (ReplaceAll p q r) x = PP (ReplaceAllT p q r) x eval _ = eval (Proxy @(ReplaceAllT p q r)) +-- | replaces the first value using regex @p@ with a replacement function @q@ inside the value @r@ using regex options @rs@ data ReplaceOne' (rs :: [ROpt]) p q r deriving Show type ReplaceOneT' (rs :: [ROpt]) p q r = ReplaceImpl 'False rs p q r @@ -437,21 +444,7 @@ 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) --- Val "123def456abc" --- --- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" >> Head >> Snd >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z") "Date(1530144000123+0530)" --- Val 2018-06-28 05:30:00.123 +0530 --- --- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" >> Head >> Snd >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z") "Date(1593460089052+0800)" --- Val 2020-06-30 03:48:09.052 +0800 --- --- >>> pz @(Rescan "^Date\\((\\d+)(\\d{3}[+-]\\d{4})\\)" >> Head >> Snd >> (Id !! 0 <> "." <> Id !! 1) >> ParseTimeP ZonedTime "%s%Q%z") "Date(1593460089052+0800)" --- Val 2020-06-30 03:48:09.052 +0800 --- +-- | replaces first value using regex @p@ with a replacement function @q@ inside the value @r@ data ReplaceOne p q r deriving Show type ReplaceOneT p q r = ReplaceOne' '[] p q r @@ -459,6 +452,14 @@ 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@ using regex options @rs@ +data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r deriving Show +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)) + -- | replace all occurrences of string @p@ with @q@ in @r@ -- -- >>> pl @(ReplaceAllString 'ROverWrite "abc" "def" Id) "123abc456abc" @@ -485,13 +486,9 @@ -- Present "123AbC456abcdef" (ReplaceAll (abc) 123AbC456abc | 123AbC456abcdef) -- Val "123AbC456abcdef" -- -data ReplaceAllString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r deriving Show -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)) - +-- >>> pz @(ReplaceAllString 'ROverWrite "\\." ":" Id) "141.201.1.22" +-- Val "141:201:1:22" +-- data ReplaceAllString o p q r deriving Show type ReplaceAllStringT o p q r = ReplaceAllString' '[] o p q r @@ -499,6 +496,7 @@ type PP (ReplaceAllString o p q r) x = PP (ReplaceAllStringT o p q r) x eval _ = eval (Proxy @(ReplaceAllStringT o p q r)) +-- | same as 'ReplaceOneString' but allow setting regex options with @rs@ data ReplaceOneString' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r deriving Show type ReplaceOneStringT' (rs :: [ROpt]) (o :: ReplaceFnSub) p q r = ReplaceOne' rs p (ReplaceFn o q) r @@ -506,6 +504,18 @@ 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)) +-- | replace first occurrence of string @p@ with @q@ in @r@ +-- +-- >>> pl @(ReplaceOneString 'ROverWrite "abc" "def" Id) "123abc456abc" +-- Present "123def456abc" (ReplaceOne (abc) 123abc456abc | 123def456abc) +-- Val "123def456abc" +-- +-- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" >> Head >> Snd >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z") "Date(1530144000123+0530)" +-- Val 2018-06-28 05:30:00.123 +0530 +-- +-- >>> pz @(Rescan "^Date\\((\\d+[+-]\\d{4})\\)" >> Head >> Snd >> Id !! 0 >> ReplaceOneString 'RPrepend "\\d{3}[+-]" "." Id >> ParseTimeP ZonedTime "%s%Q%z") "Date(1593460089052+0800)" +-- Val 2020-06-30 03:48:09.052 +0800 +-- data ReplaceOneString (o :: ReplaceFnSub) p q r deriving Show type ReplaceOneStringT (o :: ReplaceFnSub) p q r = ReplaceOneString' '[] o p q r
src/Predicate/Data/String.hs view
@@ -79,7 +79,7 @@ b = (fl . fr) p in pure $ mkNode opts (Val (b ^. DTL.packed)) (msg0 <> litL opts b <> litVerbose opts " | " p) [] --- | similar to 'T.stripStart' +-- | similar to 'Data.Text.stripStart' -- -- >>> pz @(Snd >> TrimL) (20," abc ") -- Val "abc " @@ -91,7 +91,7 @@ type PP TrimL x = PP TrimLT x eval _ = eval (Proxy @TrimLT) --- | similar to 'T.stripEnd' +-- | similar to 'Data.Text.stripEnd' -- -- >>> pz @(Snd >> TrimR) (20," abc ") -- Val " abc" @@ -109,7 +109,7 @@ type PP TrimR x = PP TrimRT x eval _ = eval (Proxy @TrimRT) --- | similar to 'T.strip' +-- | similar to 'Data.Text.strip' -- -- >>> pz @(Snd >> TrimBoth) (20," abc ") -- Val "abc" @@ -154,7 +154,7 @@ in if after == p then Just before else Nothing in mkNode opts (Val (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' +-- | similar to 'Data.Text.stripLeft' -- -- >>> pz @(StripL "xyz" Id) "xyzHello" -- Val (Just "Hello") @@ -172,7 +172,7 @@ type PP (StripL p q) x = PP (StripLT p q) x eval _ = eval (Proxy @(StripLT p q)) --- | similar to 'T.stripRight' +-- | similar to 'Data.Text.stripRight' -- -- >>> pz @(StripR "xyz" Id) "Hello xyz" -- Val (Just "Hello ") @@ -215,7 +215,7 @@ let msg1 = msg0 <> (if ignore then "I" else "") <> " | " <> p in mkNodeB opts (on ff lwr p q) (msg1 <> " " <> litL opts q) [hh pp, hh qq] --- | similar to 'isPrefixOf' for strings +-- | similar to 'Data.List.isPrefixOf' for strings -- -- >>> pl @(IsPrefixC "xy" Id) "xyzabw" -- True (IsPrefixC | xy xyzabw) @@ -235,7 +235,7 @@ type PP (IsPrefixC p q) x = PP (IsPrefixCT p q) x eval _ = evalBool (Proxy @(IsPrefixCT p q)) --- | similar to 'isInfixOf' for strings +-- | similar to 'Data.List.isInfixOf' for strings -- -- >>> pl @(IsInfixC "ab" Id) "xyzabw" -- True (IsInfixC | ab xyzabw) @@ -260,7 +260,7 @@ type PP (IsInfixC p q) x = PP (IsInfixCT p q) x eval _ = evalBool (Proxy @(IsInfixCT p q)) --- | similar to 'isSuffixOf' for strings +-- | similar to 'Data.List.isSuffixOf' for strings -- -- >>> pl @(IsSuffixC "bw" Id) "xyzabw" -- True (IsSuffixC | bw xyzabw) @@ -280,7 +280,7 @@ type PP (IsSuffixC p q) x = PP (IsSuffixCT p q) x eval _ = evalBool (Proxy @(IsSuffixCT p q)) --- | similar to case insensitive 'isPrefixOf' for strings +-- | similar to case insensitive 'Data.List.isPrefixOf' for strings -- -- >>> pz @(IsPrefixCI "abc" "aBcbCd") () -- Val True @@ -292,7 +292,7 @@ type PP (IsPrefixCI p q) x = PP (IsPrefixCIT p q) x eval _ = evalBool (Proxy @(IsPrefixCIT p q)) --- | similar to case insensitive 'isInfixOf' for strings +-- | similar to case insensitive 'Data.List.isInfixOf' for strings -- -- >>> pl @(IsInfixCI "aB" Id) "xyzAbw" -- True (IsInfixCI | aB xyzAbw) @@ -308,7 +308,7 @@ type PP (IsInfixCI p q) x = PP (IsInfixCIT p q) x eval _ = evalBool (Proxy @(IsInfixCIT p q)) --- | similar to case insensitive 'isSuffixOf' for strings +-- | similar to case insensitive 'Data.List.isSuffixOf' for strings -- data IsSuffixCI p q deriving Show type IsSuffixCIT p q = IsFixImplC 'GT 'True p q
src/Predicate/Data/These.hs view
@@ -71,7 +71,7 @@ -- >>> 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 +-- | similar to 'Data.These.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] -- Val ("ac",[2,4,99],[('z',1),('a',2)]) @@ -95,7 +95,7 @@ b = partitionThese as in pure $ mkNode opts (Val b) (show3 opts msg0 b as) [] --- | similar to 'TheseC.catThis' +-- | similar to 'Data.These.Combinators.catThis' -- -- >>> pz @(Thiss) [That 1, This 'a', These 'b' 33, This 'd', That 4] -- Val "ad" @@ -113,7 +113,7 @@ type PP Thiss x = PP ThissT x eval _ = eval (Proxy @ThissT) --- | similar to 'TheseC.catThat' +-- | similar to 'Data.These.Combinators.catThat' -- -- >>> pl @Thats [This 1, This 10,That 'x', This 99, That 'y'] -- Present "xy" ((>>) "xy" | {Snd "xy" | ([1,10,99],"xy",[])}) @@ -126,7 +126,7 @@ type PP Thats x = PP ThatsT x eval _ = eval (Proxy @ThatsT) --- | similar to 'TheseC.catThese' +-- | similar to 'Data.These.Combinators.catThese' -- -- >>> pz @(ZipThese Id Tail >> Theses) [1..10] -- Val [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8),(8,9),(9,10)] @@ -138,7 +138,7 @@ type PP Theses x = PP ThesesT x eval _ = eval (Proxy @ThesesT) --- | similar to 'TheseC.catHere' +-- | similar to 'Data.These.Combinators.catHere' -- -- >>> pz @(ZipThese Id Tail >> Heres) [1..10] -- Val [1,2,3,4,5,6,7,8,9,10] @@ -154,7 +154,7 @@ b = TheseC.catHere as in pure $ mkNode opts (Val b) (show3 opts msg0 b as) [] --- | similar to 'TheseC.catThere' +-- | similar to 'Data.These.Combinators.catThere' -- -- >>> pz @(ZipThese Id Tail >> Theres) [1..10] -- Val [2,3,4,5,6,7,8,9,10] @@ -275,6 +275,7 @@ type PP (MkThis t p) x = PP (MkThisT t p) x eval _ = eval (Proxy @(MkThisT t p)) +-- | similar to 'MkThat' where @t@ references the type data MkThat' t p deriving Show instance ( Show (PP p x)
src/Predicate/Data/Tuple.hs view
@@ -40,6 +40,7 @@ -- ** inductive tuples , EachITuple , ToITuple + , FromITuple , ReverseITuple , ToITupleList @@ -177,7 +178,7 @@ -- >>> pz @(Pred *** ShowP Id) (13, True) -- Val (12,"True") -- --- >>> pl @(FlipT (***) Len (Id * 12)) (99,"cdef") +-- >>> pl @(Flip (***) Len (Id * 12)) (99,"cdef") -- Present (1188,4) ((***) (1188,4) | (99,"cdef")) -- Val (1188,4) -- @@ -378,6 +379,9 @@ -- | similar to 'Data.Function.on': may require kind signatures: Both is a better choice -- +-- >>> pz @(On (==!) Len) ("1ss","x2") -- or use Comparing or Both+Compare +-- Val GT +-- -- >>> pz @('(4,2) >> On (**) (FromIntegral _)) () -- Val 16.0 -- @@ -390,7 +394,6 @@ -- >>> pz @(Both (Id * Id) >> ((Fst + Snd) ** (1 % 2 >> FromRational _))) (3,4) -- equivalent to the above but easier on ghc -- Val 5.0 -- - data On (p :: Type -> Type -> k2) q deriving Show instance ( P q a @@ -537,6 +540,25 @@ eval _ opts x = do let msg0 = "ToITuple" pure $ mkNode opts (Val (toITupleC x)) msg0 [] + +-- | create flat tuples from inductive tuples +-- +-- >>> pz @FromITuple (2,(3,(True,('y',())))) +-- Val (2,3,True,'y') +-- +-- >>> pz @FromITuple () +-- Val () +-- +-- >>> pz @FromITuple (1,()) +-- Val 1 +-- +data FromITuple deriving Show + +instance FromITupleC x => P FromITuple x where + type PP FromITuple x = FromITupleP x + eval _ opts x = do + let msg0 = "FromITuple" + pure $ mkNode opts (Val (fromITupleC x)) msg0 [] -- | reverse an inductive tuple --
src/Predicate/Examples/Common.hs view
@@ -132,7 +132,7 @@ -- | @op@ type for validating an ip4 address using a predicate type Ip4op' = BoolsN (PrintT "octet %d out of range 0-255 found %d" Id) 4 (0 <..> 0xff) -- | @op@ type for validating an ip4 address using a guard -type Ip4op = GuardsN (PrintT "octet %d out of range 0-255 found %d" Id) 4 (0 <..> 0xff) >> 'True +type Ip4op = GuardsN 4 (PrintT "octet %d out of range 0-255 found %d" Id) (0 <..> 0xff) >> 'True -- | @fmt@ type for formatting an ip4 address type Ip4fmt = PrintL 4 "%03d.%03d.%03d.%03d" Id
src/Predicate/Misc.hs view
@@ -63,6 +63,7 @@ -- ** inductive tuples , ToITupleC(..) + , FromITupleC(..) , ToITupleListC(..) , ReverseITupleC(..) , TupleC(..) @@ -121,12 +122,11 @@ , (~>) , errorInProgram , drawTreeU - , asProxyLeft - , asProxyRight , removeAnsi , _Id , sum' , product' + , cycle' , cmpOf ) where import qualified GHC.TypeNats as GN @@ -316,11 +316,10 @@ -- >>> toITupleC (123,'x') -- (123,('x',())) -- - class ToITupleC x where type ToITupleP x toITupleC :: x -> ToITupleP x -instance (GL.TypeError ('GL.Text "ToITupleC: inductive tuple cannot be empty")) => ToITupleC () where +instance (GL.TypeError ('GL.Text "ToITupleC: invalid empty tuple")) => ToITupleC () where type ToITupleP () = () toITupleC () = () instance ToITupleC (a,b) where @@ -357,6 +356,56 @@ type ToITupleP (a,b,c,d,e,f,g,h,i,j,k,l) = (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,(l,())))))))))))) toITupleC (a,b,c,d,e,f,g,h,i,j,k,l) = (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,(l,())))))))))))) +-- | takes an inductive tuple and creates a flat n-tuple +-- +-- >>> fromITupleC (123,('x',(False,("abc",())))) +-- (123,'x',False,"abc") +-- +-- >>> fromITupleC (123,('x',())) +-- (123,'x') +-- +class FromITupleC x where + type FromITupleP x + fromITupleC :: x -> FromITupleP x +instance FromITupleC () where + type FromITupleP () = () + fromITupleC () = () +instance FromITupleC (a,()) where + type FromITupleP (a,()) = a + fromITupleC (a,()) = a +instance FromITupleC (a,(b,())) where + type FromITupleP (a,(b,())) = (a,b) + fromITupleC (a,(b,())) = (a,b) +instance FromITupleC (a,(b,(c,()))) where + type FromITupleP (a,(b,(c,()))) = (a,b,c) + fromITupleC (a,(b,(c,()))) = (a,b,c) +instance FromITupleC (a,(b,(c,(d,())))) where + type FromITupleP (a,(b,(c,(d,())))) = (a,b,c,d) + fromITupleC (a,(b,(c,(d,())))) = (a,b,c,d) +instance FromITupleC (a,(b,(c,(d,(e,()))))) where + type FromITupleP (a,(b,(c,(d,(e,()))))) = (a,b,c,d,e) + fromITupleC (a,(b,(c,(d,(e,()))))) = (a,b,c,d,e) +instance FromITupleC (a,(b,(c,(d,(e,(f,())))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,())))))) = (a,b,c,d,e,f) + fromITupleC (a,(b,(c,(d,(e,(f,())))))) = (a,b,c,d,e,f) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,()))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,()))))))) = (a,b,c,d,e,f,g) + fromITupleC (a,(b,(c,(d,(e,(f,(g,()))))))) = (a,b,c,d,e,f,g) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,(h,())))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,(h,())))))))) = (a,b,c,d,e,f,g,h) + fromITupleC (a,(b,(c,(d,(e,(f,(g,(h,())))))))) = (a,b,c,d,e,f,g,h) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,()))))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,(h,(i,()))))))))) = (a,b,c,d,e,f,g,h,i) + fromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,()))))))))) = (a,b,c,d,e,f,g,h,i) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,())))))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,())))))))))) = (a,b,c,d,e,f,g,h,i,j) + fromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,())))))))))) = (a,b,c,d,e,f,g,h,i,j) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,()))))))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,()))))))))))) = (a,b,c,d,e,f,g,h,i,j,k) + fromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,()))))))))))) = (a,b,c,d,e,f,g,h,i,j,k) +instance FromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,(l,())))))))))))) where + type FromITupleP (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,(l,())))))))))))) = (a,b,c,d,e,f,g,h,i,j,k,l) + fromITupleC (a,(b,(c,(d,(e,(f,(g,(h,(i,(j,(k,(l,())))))))))))) = (a,b,c,d,e,f,g,h,i,j,k,l) -- | takes a list of size @n@ and converts it to an inductive tuple. see 'Predicate.Data.ReadShow.PrintL' -- @@ -630,7 +679,7 @@ p ~> q = not p || q infixr 1 ~> --- | extract the first element from a n-tuple +-- | extract element 1 from a n-tuple class ExtractL1C tp where type ExtractL1T tp extractL1C :: tp -> ExtractL1T tp @@ -656,7 +705,7 @@ type ExtractL1T (a,b,c,d,e,f,g,h) = a extractL1C (a,_,_,_,_,_,_,_) = a --- | extract the second element from a n-tuple +-- | extract element 2 from a n-tuple class ExtractL2C tp where type ExtractL2T tp extractL2C :: tp -> ExtractL2T tp @@ -682,13 +731,13 @@ type ExtractL2T (a,b,c,d,e,f,g,h) = b extractL2C (_,b,_,_,_,_,_,_) = b --- | extract the third element from a n-tuple +-- | extract element 3 from a n-tuple 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" + type ExtractL3T (a,b) = GL.TypeError ('GL.Text "L3 doesn't work for 2-tuples") + extractL3C _ = errorInProgram "L3 doesn't work for 2-tuples" instance ExtractL3C (a,b,c) where type ExtractL3T (a,b,c) = c extractL3C (_,_,c) = c @@ -708,7 +757,7 @@ type ExtractL3T (a,b,c,d,e,f,g,h) = c extractL3C (_,_,c,_,_,_,_,_) = c --- | extract the fourth element from a n-tuple +-- | extract element 4 from a n-tuple class ExtractL4C tp where type ExtractL4T tp extractL4C :: tp -> ExtractL4T tp @@ -734,7 +783,7 @@ type ExtractL4T (a,b,c,d,e,f,g,h) = d extractL4C (_,_,_,d,_,_,_,_) = d --- | extract the fifth element from a n-tuple +-- | extract element 5 from a n-tuple class ExtractL5C tp where type ExtractL5T tp extractL5C :: tp -> ExtractL5T tp @@ -760,7 +809,7 @@ type ExtractL5T (a,b,c,d,e,f,g,h) = e extractL5C (_,_,_,_,e,_,_,_) = e --- | extract the sixth element from a n-tuple +-- | extract element 6 from a n-tuple class ExtractL6C tp where type ExtractL6T tp extractL6C :: tp -> ExtractL6T tp @@ -786,7 +835,7 @@ type ExtractL6T (a,b,c,d,e,f,g,h) = f extractL6C (_,_,_,_,_,f,_,_) = f --- | extract the seventh element from a n-tuple +-- | extract element 7 from a n-tuple class ExtractL7C tp where type ExtractL7T tp extractL7C :: tp -> ExtractL7T tp @@ -812,7 +861,7 @@ type ExtractL7T (a,b,c,d,e,f,g,h) = g extractL7C (_,_,_,_,_,_,g,_) = g --- | extract the eighth element from a n-tuple +-- | extract element 8 from a n-tuple class ExtractL8C tp where type ExtractL8T tp extractL8C :: tp -> ExtractL8T tp @@ -956,8 +1005,13 @@ where isPrime' [] _ = errorInProgram "primes is empty" isPrime' (p:ps) n = p*p > n || n `rem` p /= 0 && isPrime' ps n - primes' = 7 : filter (isPrime' primes') (scanl (+) 11 $ cycle [2,4,2,4,6,2,6,4]) + primes' = 7 : filter (isPrime' primes') (scanl (+) 11 $ cycle' [2,4,2,4,6,2,6,4]) +-- | similar to 'cycle' but if the list is empty will return an empty list +cycle' :: [a] -> [a] +cycle' [] = [] +cycle' xs = xs' where xs' = xs ++ xs' + -- | pretty print 'Ordering' prettyOrd :: Ordering -> String prettyOrd = \case @@ -1219,12 +1273,6 @@ shift one other = zipWith (++) (one : repeat other) -asProxyRight :: proxy a -> proxy1 a -> proxy1 a -asProxyRight = flip const - -asProxyLeft :: proxy a -> proxy1 a -> proxy a -asProxyLeft = const - -- | strip ansi characters from a string and print it (for doctests) removeAnsi :: Show a => Either String a -> IO () removeAnsi = putStrLn . removeAnsiImpl @@ -1243,6 +1291,7 @@ in concat $ unfoldr f e Right a -> show a +-- | 'Identity' lens _Id :: Lens (Identity a) (Identity b) a b _Id afb (Identity a) = Identity <$> afb a @@ -1270,9 +1319,11 @@ instance SwapC ((,,,,,,) a b c d e) where swapC (a,b,c,d,e,f,g) = (a,b,c,d,e,g,f) +-- | strict version of 'sum' sum' :: (Foldable t, Num a) => t a -> a sum' = foldl' (+) 0 +-- | strict version of 'product' product' :: (Foldable t, Num a) => t a -> a product' = foldl' (*) 1
src/Predicate/Refined.hs view
@@ -71,7 +71,7 @@ deriving stock (Show, TH.Lift) deriving newtype (Eq, Ord, NFData) --- | extract the value from Refined +-- | extract the value from 'Refined' unRefined :: forall k (opts :: Opt) (p :: k) a . Refined opts p a -> a @@ -87,10 +87,11 @@ -- >>> pureTryTest $ fromString @(Refined OL (ReadP Int Id >> Id > 244) String) "52" -- Left () -- -instance RefinedC opts p String => IsString (Refined opts p String) where +instance RefinedC opts p String + => IsString (Refined opts p String) where fromString s = case newRefined @opts @p s of - Left w -> error $ "Refined(fromString):" ++ errorDisplay (getOpt @opts) w + Left w -> error $ "Refined(IsString:fromString):" ++ errorDisplay (getOpt @opts) w Right r -> r errorDisplay :: POpts -> Msg0 -> String @@ -238,18 +239,21 @@ Just a -> pure $ unsafeRefined a in f 0 +-- | holds the results of creating a 'Refined' value for display data Msg0 = Msg0 { m0BoolE :: !(Either String Bool) , m0Short :: !String , m0Long :: !String , m0ValBoolColor :: !String } deriving Eq +-- | verbose display of 'Msg0' showMsg0 :: Msg0 -> String showMsg0 (Msg0 a b c d) = "Msg0 [" ++ show a ++ "]\nShort[" ++ b ++ "]\nLong[" ++ c ++ "]\nColor[" ++ d ++ "]" instance Show Msg0 where show = m0Long +-- | returns a 'Refined' value if @a@ is valid for the predicate @p@ for any 'MonadEval' instance newRefined' :: forall opts p a m . ( MonadEval m , RefinedC opts p a @@ -259,14 +263,14 @@ newRefined' a = do let o = getOpt @opts pp <- evalBool (Proxy @p) o a - let r = colorValBool o (_ttVal pp) + let r = colorValBool o (pp ^. ttVal) s = prtTree o pp msg0 = Msg0 (pp ^. ttVal . _ValEither) (topMessage pp) s r pure $ case getValueLR NoInline o "" pp [] of Right True -> Right (Refined a) _ -> Left msg0 --- | returns a 'Refined' value if @a@ is valid for the predicate @p@ +-- | returns a pure 'Refined' value if @a@ is valid for the predicate @p@ -- -- >>> newRefined @OL @(ReadP Int Id > 99) "123" -- Right (Refined "123") @@ -322,7 +326,6 @@ -- >>> newRefined @OU @((Id $$ 13) > 100) (\x -> x * 14) ^? _Right . to unRefined . to ($ 99) -- Just 1386 -- - newRefined :: forall opts p a . RefinedC opts p a => a @@ -344,7 +347,7 @@ in case getValueLR NoInline o "" tt [] of Right True -> Refined a _ -> let s = prtTree o tt - bp = colorValBool o (_ttVal tt) + bp = colorValBool o (tt ^. ttVal) in case oDebug o of DZero -> error bp DLite -> error $ bp ++ nullIf "\n" s
src/Predicate/Refined2.hs view
@@ -97,9 +97,11 @@ -- data Refined2 (opts :: Opt) ip op i = Refined2 !(PP ip i) !i +-- | field accessor for the converted input value in 'Refined2' r2In :: Refined2 (opts :: Opt) ip op i -> PP ip i r2In (Refined2 ppi _) = ppi +-- | field accessor for the original input value in 'Refined2' r2Out :: Refined2 (opts :: Opt) ip op i -> i r2Out (Refined2 _ i) = i @@ -168,7 +170,7 @@ ) => IsString (Refined2 opts ip op i) where fromString i = case newRefined2 i of - Left e -> error $ "Refined2(fromString):" ++ show e + Left e -> error $ "Refined2(IsString:fromString):" ++ show e Right r -> r -- read instance from -ddump-deriv @@ -230,7 +232,7 @@ -- Right (Refined2 254 "00fe") -- -- >>> removeAnsi $ A.eitherDecode' @(Refined2 OAN (ReadBase Int 16) (Id > 10 && Id < 256) String) "\"00fe443a\"" --- Error in $: Refined2:Step 2. False Boolean Check(op) | {True && False | (16663610 < 256)} +-- Error in $: Refined2(FromJSON:parseJSON):Step 2. False Boolean Check(op) | {True && False | (16663610 < 256)} -- *** Step 1. Success Initial Conversion(ip) (16663610) *** -- P ReadBase(Int,16) 16663610 -- | @@ -257,7 +259,7 @@ parseJSON z = do i <- parseJSON @i z case newRefined2 i of - Left e -> fail $ "Refined2:" ++ show e + Left e -> fail $ "Refined2(FromJSON:parseJSON):" ++ show e Right r -> return r -- | 'Arbitrary' instance for 'Refined2' @@ -327,7 +329,7 @@ -- Refined2 2019-04-23 "2019-04-23" -- -- >>> removeAnsi $ (view _3 +++ view _3) $ B.decodeOrFail @K2 (B.encode r) --- Refined2:Step 2. False Boolean Check(op) | {2019-05-30 <= 2019-04-23} +-- Refined2(Binary:get):Step 2. False Boolean Check(op) | {2019-05-30 <= 2019-04-23} -- *** Step 1. Success Initial Conversion(ip) (2019-04-23) *** -- P ReadP Day 2019-04-23 -- | @@ -352,7 +354,7 @@ get = do i <- B.get @i case newRefined2 i of - Left e -> fail $ "Refined2:" ++ show e + Left e -> fail $ "Refined2(Binary:get):" ++ show e Right r -> return r put (Refined2 _ r) = B.put @i r @@ -370,6 +372,7 @@ | RTTrue !a !(Tree PE) !(Tree PE) -- op true deriving Show +-- | version for creating a 'Refined2' value that works for any 'MonadEval' instance newRefined2' :: forall opts ip op i m . ( MonadEval m , Refined2C opts ip op i @@ -379,7 +382,7 @@ -> m (Either Msg2 (Refined2 opts ip op i)) newRefined2' = newRefined2P' Proxy --- | same as 'newRefined2P' but runs in IO +-- | same as 'newRefined2P' but runs for any MonadEval instance newRefined2P' :: forall opts ip op i proxy m . ( MonadEval m , Refined2C opts ip op i @@ -392,13 +395,13 @@ (ret,mr) <- eval2M i return $ maybe (Left $ prt2Impl (getOpt @opts) ret) Right mr --- | pure version for extracting Refined2 +-- | pure version for creating a 'Refined2' value -- -- >>> newRefined2 @OZ @(ReadBase Int 16) @(Lt 255) "00fe" -- Right (Refined2 254 "00fe") -- --- >>> newRefined2 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "0x%X is too large" Id) (Lt 253)) "00fe" --- Left Step 2. Failed Boolean Check(op) | 0xFE is too large +-- >>> newRefined2 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "%#x is too large" Id) (Lt 253)) "00fe" +-- Left Step 2. Failed Boolean Check(op) | 0xfe is too large -- -- >>> newRefined2 @OZ @(ReadBase Int 16) @(Lt 255) "00fg" -- Left Step 1. Failed Initial Conversion(ip) | invalid base 16 @@ -438,6 +441,15 @@ -> Either Msg2 (Refined2 opts ip op i) newRefined2 = newRefined2P Proxy +-- | create a Refined2 using a 4-tuple proxy and aggregate the results on failure +-- +-- >>> type T4 k = '(OZ, MkDayExtra Id >> 'Just Id, GuardBool "expected a Sunday" (Thd == 7), k) +-- >>> newRefined2P (Proxy @(T4 _)) (2019,10,12) +-- Left Step 2. Failed Boolean Check(op) | expected a Sunday +-- +-- >>> newRefined2P (Proxy @(T4 _)) (2019,10,13) +-- Right (Refined2 (2019-10-13,41,7) (2019,10,13)) +-- newRefined2P :: forall opts ip op i . ( Refined2C opts ip op i , Show (PP ip i) @@ -448,6 +460,7 @@ let (ret,mr) = runIdentity $ eval2M i in maybe (Left $ prt2Impl (getOpt @opts) ret) Right mr +-- | create a Refined2 value using a 4-tuple proxy (see 'mkProxy2') eval2P :: forall opts ip op i m . ( Refined2C opts ip op i , MonadEval m @@ -457,6 +470,7 @@ -> m (RResults2 (PP ip i), Maybe (Refined2 opts ip op i)) eval2P _ = eval2M +-- | workhorse for creating 'Refined2' values eval2M :: forall opts ip op i m . ( MonadEval m , Refined2C opts ip op i @@ -475,6 +489,7 @@ (Left e,t2) -> (RTF a t1 e t2, Nothing) (Left e,t1) -> pure (RF e t1, Nothing) +-- | holds the results of creating a 'Refined2' value for display data Msg2 = Msg2 { m2Desc :: !String , m2Short :: !String , m2Long :: !String @@ -484,6 +499,7 @@ instance Show Msg2 where show (Msg2 a b c _d) = a <> nullIf " | " b <> nullIf "\n" c +-- | format the output from creating a 'Refined2' value into 'Msg2' prt2Impl :: forall a . Show a => POpts -> RResults2 a
src/Predicate/Refined3.hs view
@@ -54,7 +54,6 @@ , mkProxy3 , mkProxy3' , MakeR3 - , MakeR3' -- ** unsafe methods for creating Refined3 , unsafeRefined3 @@ -118,9 +117,11 @@ type role Refined3 phantom nominal nominal nominal nominal +-- | field accessor for the converted input value in 'Refined3' r3In :: Refined3 opts ip op fmt i -> PP ip i r3In (Refined3 ppi _) = ppi +-- | field accessor for the converted output value in 'Refined3' r3Out :: Refined3 opts ip op fmt i -> i r3Out (Refined3 _ i) = i @@ -190,7 +191,7 @@ ) => IsString (Refined3 opts ip op fmt String) where fromString s = case newRefined3 s of - Left e -> error $ "Refined3(fromString):" ++ show e + Left e -> error $ "Refined3(IsString:fromString):" ++ show e Right r -> r -- read instance from -ddump-deriv @@ -253,7 +254,7 @@ -- Right (Refined3 254 "fe") -- -- >>> removeAnsi $ A.eitherDecode' @(Refined3 OAN (ReadBase Int 16) (Id > 10 && Id < 256) (ShowBase 16) String) "\"00fe443a\"" --- Error in $: Refined3:Step 2. False Boolean Check(op) | {True && False | (16663610 < 256)} +-- Error in $: Refined3(FromJSON:parseJSON):Step 2. False Boolean Check(op) | {True && False | (16663610 < 256)} -- *** Step 1. Success Initial Conversion(ip) (16663610) *** -- P ReadBase(Int,16) 16663610 -- | @@ -280,7 +281,7 @@ parseJSON z = do i <- parseJSON @i z case newRefined3 i of - Left e -> fail $ "Refined3:" ++ show e + Left e -> fail $ "Refined3(FromJSON:parseJSON):" ++ show e Right r -> return r -- | 'Arbitrary' instance for 'Refined3' @@ -346,7 +347,7 @@ -- Refined3 2019-04-23 "2019-04-23" -- -- >>> removeAnsi $ (view _3 +++ view _3) $ B.decodeOrFail @K2 (B.encode r) --- Refined3:Step 2. False Boolean Check(op) | {2019-05-30 <= 2019-04-23} +-- Refined3(Binary:get):Step 2. False Boolean Check(op) | {2019-05-30 <= 2019-04-23} -- *** Step 1. Success Initial Conversion(ip) (2019-04-23) *** -- P ReadP Day 2019-04-23 -- | @@ -371,7 +372,7 @@ get = do i <- B.get @i case newRefined3 i of - Left e -> fail $ "Refined3:" ++ show e + Left e -> fail $ "Refined3(Binary:get):" ++ show e Right r -> return r put (Refined3 _ r) = B.put @i r @@ -414,9 +415,6 @@ type family MakeR3 p where MakeR3 '(opts,ip,op,fmt,i) = Refined3 opts ip op fmt i -type family MakeR3' opts p where - MakeR3' opts '(ip,op,fmt,i) = Refined3 opts ip op fmt i - -- | An ADT that summarises the results of evaluating Refined3 representing all possible states data RResults3 a = RF !String !(Tree PE) -- Left e @@ -436,7 +434,7 @@ -> m (Either Msg3 (Refined3 opts ip op fmt i)) newRefined3' = newRefined3P' Proxy --- | same as 'newRefined3P' but runs in IO +-- | same as 'newRefined3P' but runs in any MonadEval instance newRefined3P' :: forall opts ip op fmt i proxy m . ( MonadEval m , Refined3C opts ip op fmt i @@ -454,8 +452,8 @@ -- >>> newRefined3 @OZ @(ReadBase Int 16) @(Lt 255) @(PrintF "%x" Id) "00fe" -- Right (Refined3 254 "fe") -- --- >>> newRefined3 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "0x%X is too large" Id) (Lt 253)) @(PrintF "%x" Id) "00fe" --- Left Step 2. Failed Boolean Check(op) | 0xFE is too large +-- >>> newRefined3 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "%#x is too large" Id) (Lt 253)) @(PrintF "%x" Id) "00fe" +-- Left Step 2. Failed Boolean Check(op) | 0xfe is too large -- -- >>> newRefined3 @OZ @(ReadBase Int 16) @(Lt 255) @(PrintF "%x" Id) "00fg" -- Left Step 1. Failed Initial Conversion(ip) | invalid base 16 @@ -536,6 +534,7 @@ -> m (RResults3 (PP ip i), Maybe (Refined3 opts ip op fmt i)) eval3P _ = eval3M +-- | workhorse for creating 'Refined3' values eval3M :: forall opts ip op fmt i m . ( MonadEval m , Refined3C opts ip op fmt i @@ -558,7 +557,7 @@ (Left e,t2) -> pure (RTF a t1 e t2, Nothing) (Left e,t1) -> pure (RF e t1, Nothing) --- | creates Refined3 value but skips the initial conversion +-- | creates a 'Refined3' value but skips the initial conversion eval3MSkip :: forall opts ip op fmt i m . ( MonadEval m , Refined3C opts ip op fmt i @@ -580,6 +579,7 @@ mkNodeSkipP :: Tree PE mkNodeSkipP = Node (PE TrueP "skipped PP ip i = Id") [] +-- | holds the results of creating a 'Refined3' value for display data Msg3 = Msg3 { m3Desc :: !String , m3Short :: !String , m3Long :: !String
src/Predicate/Refined5.hs view
@@ -148,7 +148,7 @@ ) => IsString (Refined5 opts ip op i) where fromString i = case newRefined5 i of - Left e -> error $ "Refined5(fromString):" ++ show e + Left e -> error $ "Refined5(IsString:fromString):" ++ show e Right r -> r -- read instance from -ddump-deriv @@ -210,14 +210,14 @@ -- Right (Refined5 123) -- -- >>> removeAnsi $ A.eitherDecode' @(Refined5 OL (ReadBase Int 16) (Id > 10 && Id < 256) String) "9" --- Error in $: Refined5:false boolean check | {False && True | (9 > 10)} +-- Error in $: Refined5(FromJSON:parseJSON):false boolean check | {False && True | (9 > 10)} -- False -- -- >>> A.eitherDecode' @(Refined5 OZ (ReadBase Int 16) (Id > 10 && Id < 256) String) "254" -- Right (Refined5 254) -- -- >>> removeAnsi $ A.eitherDecode' @(Refined5 OAN (ReadBase Int 16) (Id > 10 && Id < 256) String) "12345" --- Error in $: Refined5:false boolean check | {True && False | (12345 < 256)} +-- Error in $: Refined5(FromJSON:parseJSON):false boolean check | {True && False | (12345 < 256)} -- False True && False | (12345 < 256) -- | -- +- True 12345 > 10 @@ -238,7 +238,7 @@ parseJSON z = do i <- parseJSON @(PP ip i) z case evalBool5 @opts @op i of - Left e -> fail $ "Refined5:" ++ e + Left e -> fail $ "Refined5(FromJSON:parseJSON):" ++ e Right _ -> return (Refined5 i) -- | 'Arbitrary' instance for 'Refined5' @@ -293,7 +293,7 @@ get = do i <- B.get @(PP ip i) case evalBool5 @opts @op i of - Left e -> fail $ "Refined5:Binary:" ++ e + Left e -> fail $ "Refined5(Binary:get):" ++ e Right _ -> return $ Refined5 i put (Refined5 r) = B.put @(PP ip i) r @@ -303,6 +303,7 @@ ) => Hashable (Refined5 opts ip op i) where hashWithSalt s (Refined5 b) = s + hash b +-- | creating a 'Refined5' value for any 'MonadEval' newRefined5' :: forall opts ip op i m . ( MonadEval m , Refined2C opts ip op i @@ -312,7 +313,7 @@ -> m (Either Msg2 (Refined5 opts ip op i)) newRefined5' = newRefined5P' Proxy --- | same as 'newRefined5P' but runs in IO +-- | same as 'newRefined5P' but runs for any MonadEval instance newRefined5P' :: forall opts ip op i proxy m . ( MonadEval m , Refined2C opts ip op i @@ -325,13 +326,13 @@ (ret,mr) <- eval5M i return $ maybe (Left $ prt2Impl (getOpt @opts) ret) Right mr --- | pure version for extracting Refined5 +-- | pure version for creating a 'Refined5' value -- -- >>> newRefined5 @OZ @(ReadBase Int 16) @(Lt 255) "00fe" -- Right (Refined5 254) -- --- >>> newRefined5 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "0x%X is too large" Id) (Lt 253)) "00fe" --- Left Step 2. Failed Boolean Check(op) | 0xFE is too large +-- >>> newRefined5 @OZ @(ReadBase Int 16) @(GuardBool (PrintF "%#x is too large" Id) (Lt 253)) "00fe" +-- Left Step 2. Failed Boolean Check(op) | 0xfe is too large -- -- >>> newRefined5 @OZ @(ReadBase Int 16) @(Lt 255) "00fg" -- Left Step 1. Failed Initial Conversion(ip) | invalid base 16 @@ -371,6 +372,7 @@ -> Either Msg2 (Refined5 opts ip op i) newRefined5 = newRefined5P Proxy +-- | create a Refined5 using a 4-tuple proxy and aggregate the results on failure newRefined5P :: forall opts ip op i . ( Refined2C opts ip op i , Show (PP ip i) @@ -381,6 +383,7 @@ let (ret,mr) = runIdentity $ eval5M i in maybe (Left $ prt2Impl (getOpt @opts) ret) Right mr +-- | create a 'Refined5' value using a 4-tuple proxy (see 'Predicate.Refined2.mkProxy2') eval5P :: forall opts ip op i m . ( Refined2C opts ip op i , MonadEval m @@ -390,6 +393,7 @@ -> m (RResults2 (PP ip i), Maybe (Refined5 opts ip op i)) eval5P _ = eval5M +-- | workhorse for creating 'Refined5' values eval5M :: forall opts ip op i m . ( MonadEval m , Refined2C opts ip op i
src/Predicate/Util.hs view
@@ -28,14 +28,10 @@ Val(..) , _Fail , _Val - , _True - , _False , _ValEither - , val2P - , val2PBool -- ** TT typed tree - , TT(..) + , TT , ttVal , ttValBool , ttString @@ -136,7 +132,6 @@ , chkSize , chkSize2 , badLength - ) where import Predicate.Misc import GHC.TypeLits (Symbol, Nat, KnownSymbol, KnownNat) @@ -216,11 +211,14 @@ -- | semigroup for ValP -- -- >>> TrueP <> FalseP <> ValP --- ValP +-- FalseP -- -- >>> ValP <> TrueP <> FalseP -- FalseP -- +-- >>> ValP <> TrueP <> ValP +-- TrueP +-- -- >>> FailP "abc" <> (TrueP <> FalseP) <> FailP "def" -- FailP "abc | def" -- @@ -240,9 +238,11 @@ FailP s <> FailP s1 = FailP (jamSS s s1) FailP s <> _ = FailP s _ <> FailP s = FailP s - _ <> ValP = ValP - _ <> TrueP = TrueP + FalseP <> _ = FalseP _ <> FalseP = FalseP + TrueP <> _ = TrueP + _ <> TrueP = TrueP + ValP <> ValP = ValP instance Monoid ValP where mempty = ValP @@ -328,7 +328,7 @@ , _ttString :: !String -- ^ detailed information eg input and output and text , _ttForest :: !(Forest PE) -- ^ the child nodes } deriving stock (Functor, Read, Show, Eq, Foldable, Traversable, Generic, Generic1) - deriving TH.Lift + deriving stock TH.Lift -- dont expose lenses for _ttValP and _ttVal as they must be kept in sync: see ttVal makeLensesFor [("_ttString","ttString"),("_ttForest","ttForest")] ''TT @@ -341,16 +341,20 @@ mempty = TT mempty mempty mempty mempty instance Applicative TT where - pure a = TT ValP (pure a) "" [] + pure a = TT ValP (Val a) "" [] (<*>) = ap +fixTTValP :: ValP -> TT a -> TT a +fixTTValP bp tt = tt { _ttValP = bp <> _ttValP tt } + instance Monad TT where return = pure - z@(TT _ bt ss ts) >>= amb = + z@(TT bp bt ss ts) >>= amb = case bt of - Val a -> amb a & ttString %~ jamSS ss - & ttForest %~ (ts <>) - Fail e -> z & ttVal .~ Fail e + Val a -> fixTTValP bp $ amb a + & ttString %~ jamSS ss + & ttForest %~ (ts <>) + Fail e -> z { _ttVal = Fail e } -- | creates a Node for the evaluation tree mkNodeCopy :: POpts @@ -366,7 +370,7 @@ -> String -> [Tree PE] -> TT a -mkNode opts = mkNodeImpl opts . (view val2P &&& id) +mkNode opts = mkNodeImpl opts . (val2P &&& id) -- | creates a Node for the evaluation tree mkNodeImpl :: POpts @@ -792,7 +796,7 @@ -> Val Bool -> String colorValBool o r = - let f = colorMe o (r ^. val2PBool) + let f = colorMe o (val2PBool r) in case r of Fail e -> f "Fail" <> " " <> e Val False -> f "False" @@ -1147,44 +1151,6 @@ | isVerbose o = [hh tt] | otherwise = [] --- | prism for Val True --- --- >>> Val True ^? _True --- Just () --- --- >>> Val False ^? _True --- Nothing --- -_True :: a ~ Bool => Prism' (Val a) () -_True = - prism' (const (Val True)) - $ \case - Val True -> Just () - Val False -> Nothing - Fail {} -> Nothing - --- | prism for Val False --- --- >>> (_True # ()) ^? _True --- Just () --- --- >>> (_False # ()) ^? _False --- Just () --- --- >>> Val False ^? _False --- Just () --- --- >>> Val True ^? _False --- Nothing --- -_False :: a ~ Bool => Prism' (Val a) () -_False = - prism' (const (Val False)) - $ \case - Val False -> Just () - Val True -> Nothing - Fail {} -> Nothing - -- | iso for 'Val' -- -- >>> Val 123 ^. _ValEither @@ -1224,40 +1190,40 @@ Fail e -> Left e bw = either Fail Val --- | a lens from typed 'Val' to the untyped 'ValP' +-- | converts from a typed 'Val' to the untyped 'ValP' -- --- >>> Val True ^. val2P +-- >>> val2P (Val True) -- ValP -- --- >>> Val 123 ^. val2P +-- >>> val2P (Val 123) -- ValP -- --- >>> Fail "abc" ^. val2P +-- >>> val2P (Fail "abc") -- FailP "abc" -- -val2P :: Lens' (Val a) ValP -val2P afb bt = bt <$ afb r - where r = case bt of - Fail e -> FailP e - Val {} -> ValP +val2P :: Val a -> ValP +val2P = + \case + Fail e -> FailP e + Val {} -> ValP --- | a lens from typed 'Val' Bool to the untyped 'ValP' +-- | converts from a typed 'Val' Bool to the untyped 'ValP' -- --- >>> Val True ^. val2PBool +-- >>> val2PBool (Val True) -- TrueP -- --- >>> Val False ^. val2PBool +-- >>> val2PBool (Val False) -- FalseP -- --- >>> Fail "abc" ^. val2PBool +-- >>> val2PBool (Fail "abc") -- FailP "abc" -- -val2PBool :: a ~ Bool => Lens' (Val a) ValP -val2PBool afb bt = bt <$ afb r - where r = case bt of - Fail e -> FailP e - Val True -> TrueP - Val False -> FalseP +val2PBool :: a ~ Bool => Val a -> ValP +val2PBool = + \case + Fail e -> FailP e + Val True -> TrueP + Val False -> FalseP -- | lens that keeps 'ValP' in sync with 'Val' for TT Bool -- @@ -1274,11 +1240,7 @@ -- True -- ttValBool :: a ~ Bool => Lens' (TT a) (Val Bool) -ttValBool afb tt = (\b -> tt { _ttValP = f b, _ttVal = b }) <$> afb (_ttVal tt) - where f = \case - Fail e -> FailP e - Val True -> TrueP - Val False -> FalseP +ttValBool afb tt = (\b -> tt { _ttValP = val2PBool b, _ttVal = b }) <$> afb (_ttVal tt) -- | lens from 'TT' to 'Val' that also keeps 'ValP' in sync with 'Val' -- @@ -1292,8 +1254,5 @@ -- True -- ttVal :: Lens (TT a) (TT b) (Val a) (Val b) -ttVal afb tt = (\b -> tt { _ttValP = f b, _ttVal = b }) <$> afb (_ttVal tt) - where f = \case - Fail e -> FailP e - Val {} -> ValP +ttVal afb tt = (\b -> tt { _ttValP = val2P b, _ttVal = b }) <$> afb (_ttVal tt)
src/Predicate/Util_TH.hs view
@@ -72,6 +72,7 @@ Left m -> fail $ refinedFailMsg @opts msg0 m Right r -> [||r||] +-- | creates a 'Refined.Refined' refinement type running in IO refinedTHIO :: forall opts p i . (TH.Lift i, RefinedC opts p i) => i
test/TestJson.hs view
@@ -33,7 +33,7 @@ , testCase "testperson1 bad lastname lowercase first letter" $ expectIO (testPerson1 @OAN 4) (expectLeftWith ["lastName1", "invalid name", "diaz"]) , testCase "testperson1 bad first name lowercase first letter" $ expectIO (testPerson1 @OAN 6) (expectLeftWith ["firstName1", "not upper first(d)"]) , testCase "testperson1 age 99 out of range" $ expectIO (testPerson1 @OAN 5) (expectLeftWith ["Error in $[0].age1"]) - , testCase "parse fail person1" $ expectBT (Fail "ParseJsonFile [Person1 'OZ](test3.json) Error in $[0].ipaddress1: Refined3:Step 2. Failed Boolean Check(op) | octet 3 out of range 0-255 found 260") $ pz @(ParseJsonFile [Person1 'OZ] "test3.json") () + , testCase "parse fail person1" $ expectBT (Fail "ParseJsonFile [Person1 'OZ](test3.json) Error in $[0].ipaddress1: Refined3(FromJSON:parseJSON):Step 2. Failed Boolean Check(op) | octet 3 out of range 0-255 found 260") $ pz @(ParseJsonFile [Person1 'OZ] "test3.json") () , testCase "parse ok person1" $ expectBT (Val 5) $ pl @(ParseJsonFile [Person1 OAN] "test2.json" >> Len) () , testCase "missing file" $ expectBT (Fail "ParseJsonFile [Person1 'OZ](test2.jsoxxxn) file does not exist") $ pl @(ParseJsonFile [Person1 'OZ] "test2.jsoxxxn" >> Len) ()