{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -fexpose-all-unfoldings #-}
module PredicateTransformers where
import Control.Applicative
import Control.DeepSeq (NFData, force)
import Control.Exception
import Control.Lens hiding (index)
import Control.Monad
import Control.Monad.Writer (execWriter, tell)
import Data.Bool
import Data.Foldable (toList)
import Data.Functor.Rep (Representable (..))
import Data.Semigroup (All (..), Any (..))
import Data.Typeable
import Debug.Trace
import System.IO.Unsafe
import Control.Concurrent (myThreadId, throwTo)
import Control.Exception (SomeAsyncException)
import GHC.Conc (pseq)
class Predicatory a where
otherHand :: a -> a -> a
also :: a -> a -> a
stop :: a
continue :: a
{-# MINIMAL otherHand, also, stop, continue #-}
instance Predicatory a => Predicatory (e -> a) where
(e -> a
f otherHand :: (e -> a) -> (e -> a) -> e -> a
`otherHand` e -> a
f') e
e = e -> a
f e
e a -> a -> a
forall a. Predicatory a => a -> a -> a
`otherHand` e -> a
f' e
e
(e -> a
f also :: (e -> a) -> (e -> a) -> e -> a
`also` e -> a
f') e
e = e -> a
f e
e a -> a -> a
forall a. Predicatory a => a -> a -> a
`also` e -> a
f' e
e
stop :: e -> a
stop = \e
_ -> a
forall a. Predicatory a => a
stop
continue :: e -> a
continue = \e
_ -> a
forall a. Predicatory a => a
continue
infixr 3 `also`
infixr 2 `otherHand`
class Exceptional a where
assess :: a -> IO () -> a
instance Exceptional a => Exceptional (e -> a) where
assess :: (e -> a) -> IO () -> e -> a
assess e -> a
f IO ()
act = \e
e -> a -> IO () -> a
forall a. Exceptional a => a -> IO () -> a
assess (e -> a
f e
e) IO ()
act
data PredicateFailed = PredicateFailed
deriving (Int -> PredicateFailed -> ShowS
[PredicateFailed] -> ShowS
PredicateFailed -> String
(Int -> PredicateFailed -> ShowS)
-> (PredicateFailed -> String)
-> ([PredicateFailed] -> ShowS)
-> Show PredicateFailed
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PredicateFailed -> ShowS
showsPrec :: Int -> PredicateFailed -> ShowS
$cshow :: PredicateFailed -> String
show :: PredicateFailed -> String
$cshowList :: [PredicateFailed] -> ShowS
showList :: [PredicateFailed] -> ShowS
Show, Typeable)
instance Exception PredicateFailed
instance Predicatory Bool where
otherHand :: Bool -> Bool -> Bool
otherHand = Bool -> Bool -> Bool
(||)
also :: Bool -> Bool -> Bool
also = Bool -> Bool -> Bool
(&&)
stop :: Bool
stop = Bool
False
continue :: Bool
continue = Bool
True
instance Exceptional Bool where
assess :: Bool -> IO () -> Bool
assess Bool
b IO ()
act
| Bool
b = Bool
b
| Bool
otherwise = IO () -> ()
forall a. IO a -> a
unsafePerformIO IO ()
act () -> Bool -> Bool
forall a b. a -> b -> b
`pseq` Bool
b
instance Predicatory (IO ()) where
otherHand :: IO () -> IO () -> IO ()
otherHand IO ()
x IO ()
y = do
IO () -> [Handler ()] -> IO ()
forall a. IO a -> [Handler a] -> IO a
catches IO ()
x
[ (SomeAsyncException -> IO ()) -> Handler ()
forall a e. Exception e => (e -> IO a) -> Handler a
Handler ((SomeAsyncException -> IO ()) -> Handler ())
-> (SomeAsyncException -> IO ()) -> Handler ()
forall a b. (a -> b) -> a -> b
$ \(SomeAsyncException
ex :: SomeAsyncException) -> do
ThreadId
tid <- IO ThreadId
myThreadId
ThreadId -> SomeAsyncException -> IO ()
forall e. Exception e => ThreadId -> e -> IO ()
throwTo ThreadId
tid SomeAsyncException
ex
, (SomeException -> IO ()) -> Handler ()
forall a e. Exception e => (e -> IO a) -> Handler a
Handler ((SomeException -> IO ()) -> Handler ())
-> (SomeException -> IO ()) -> Handler ()
forall a b. (a -> b) -> a -> b
$ \(SomeException
_ex :: SomeException) -> IO ()
y
]
also :: IO () -> IO () -> IO ()
also = IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
stop :: IO ()
stop = PredicateFailed -> IO ()
forall e a. Exception e => e -> IO a
throwIO PredicateFailed
PredicateFailed
continue :: IO ()
continue = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
instance Exceptional (IO ()) where
assess :: IO () -> IO () -> IO ()
assess IO ()
x IO ()
act =
IO () -> [Handler ()] -> IO ()
forall a. IO a -> [Handler a] -> IO a
catches IO ()
x
[ (SomeAsyncException -> IO ()) -> Handler ()
forall a e. Exception e => (e -> IO a) -> Handler a
Handler ((SomeAsyncException -> IO ()) -> Handler ())
-> (SomeAsyncException -> IO ()) -> Handler ()
forall a b. (a -> b) -> a -> b
$ \(SomeAsyncException
ex :: SomeAsyncException) -> do
ThreadId
tid <- IO ThreadId
myThreadId
ThreadId -> SomeAsyncException -> IO ()
forall e. Exception e => ThreadId -> e -> IO ()
throwTo ThreadId
tid SomeAsyncException
ex
, (SomeException -> IO ()) -> Handler ()
forall a e. Exception e => (e -> IO a) -> Handler a
Handler ((SomeException -> IO ()) -> Handler ())
-> (SomeException -> IO ()) -> Handler ()
forall a b. (a -> b) -> a -> b
$ \(SomeException
ex :: SomeException) ->
IO ()
act IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> SomeException -> IO ()
forall e a. Exception e => e -> IO a
throwIO SomeException
ex
]
type Pred a = a -> Bool
type PT p a b = (a -> p) -> (b -> p)
just :: Predicatory p => PT p a (Maybe a)
just :: forall p a. Predicatory p => PT p a (Maybe a)
just = Fold (Maybe a) a -> PT p a (Maybe a)
forall p s a. Predicatory p => Fold s a -> PT p a s
allOf1 (a -> f a) -> Maybe a -> f (Maybe a)
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
Fold (Maybe a) a
_Just
left :: Predicatory p => PT p e (Either e a)
left :: forall p e a. Predicatory p => PT p e (Either e a)
left = Fold (Either e a) e -> PT p e (Either e a)
forall p s a. Predicatory p => Fold s a -> PT p a s
allOf1 (e -> f e) -> Either e a -> f (Either e a)
forall a c b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Either a c) (f (Either b c))
Fold (Either e a) e
_Left
right :: Predicatory p => PT p a (Either e a)
right :: forall p a e. Predicatory p => PT p a (Either e a)
right = Fold (Either e a) a -> PT p a (Either e a)
forall p s a. Predicatory p => Fold s a -> PT p a s
allOf1 (a -> f a) -> Either e a -> f (Either e a)
forall c a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Either c a) (f (Either c b))
Fold (Either e a) a
_Right
endingWith :: (Predicatory p, Foldable f) => PT p a (f a)
endingWith :: forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
PT p a (f a)
endingWith a -> p
_ (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> []) = p
forall a. Predicatory a => a
stop
endingWith a -> p
p (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> [a]
xs) = a -> p
p (a -> p) -> a -> p
forall a b. (a -> b) -> a -> b
$ [a] -> a
forall a. HasCallStack => [a] -> a
last [a]
xs
startingWith :: (Predicatory p, Foldable f) => PT p a (f a)
startingWith :: forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
PT p a (f a)
startingWith a -> p
p (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> (a
x : [a]
_)) = a -> p
p a
x
startingWith a -> p
_ (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList -> []) = p
forall a. Predicatory a => a
stop
soleElementOf :: Predicatory p => Fold s a -> PT p a s
soleElementOf :: forall p s a. Predicatory p => Fold s a -> PT p a s
soleElementOf Fold s a
f a -> p
p (Getting (Endo [a]) s a -> s -> [a]
forall a s. Getting (Endo [a]) s a -> s -> [a]
toListOf Getting (Endo [a]) s a
Fold s a
f -> [a
x]) = a -> p
p a
x
soleElementOf Fold s a
_ a -> p
_ s
_ = p
forall a. Predicatory a => a
stop
soleElement :: (Predicatory p, Foldable f) => PT p a (f a)
soleElement :: forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
PT p a (f a)
soleElement = Fold (f a) a -> PT p a (f a)
forall p s a. Predicatory p => Fold s a -> PT p a s
soleElementOf (a -> f a) -> f a -> f (f a)
Fold (f a) a
forall (f :: * -> *) a. Foldable f => IndexedFold Int (f a) a
IndexedFold Int (f a) a
folded
kth :: (Predicatory p, Foldable f) => Int -> PT p a (f a)
kth :: forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
Int -> PT p a (f a)
kth Int
k a -> p
p = PT p a [a]
forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
PT p a (f a)
startingWith a -> p
p ([a] -> p) -> (f a -> [a]) -> f a -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop Int
k ([a] -> [a]) -> (f a -> [a]) -> f a -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
list :: Predicatory p => [a -> p] -> [a] -> p
list :: forall p a. Predicatory p => [a -> p] -> [a] -> p
list (a -> p
p : [a -> p]
ps) (a
x : [a]
xs) = a -> p
p a
x p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` [a -> p] -> [a] -> p
forall p a. Predicatory p => [a -> p] -> [a] -> p
list [a -> p]
ps [a]
xs
list [] [] = p
forall a. Predicatory a => a
continue
list [a -> p]
_ [a]
_ = p
forall a. Predicatory a => a
stop
dist ::
(Predicatory p, Eq (f ()), Functor f, Foldable f) =>
f (a -> p) ->
f a ->
p
dist :: forall p (f :: * -> *) a.
(Predicatory p, Eq (f ()), Functor f, Foldable f) =>
f (a -> p) -> f a -> p
dist f (a -> p)
preds f a
values =
p -> p -> Bool -> p
forall a. a -> a -> Bool -> a
bool p
forall a. Predicatory a => a
stop p
forall a. Predicatory a => a
continue ((() () -> f (a -> p) -> f ()
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f (a -> p)
preds) f () -> f () -> Bool
forall a. Eq a => a -> a -> Bool
== (() () -> f a -> f ()
forall a b. a -> f b -> f a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ f a
values))
p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` [a -> p] -> [a] -> p
forall p a. Predicatory p => [a -> p] -> [a] -> p
list (f (a -> p) -> [a -> p]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f (a -> p)
preds) (f a -> [a]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f a
values)
distRep ::
Representable f =>
f (a -> p) ->
f a ->
f p
distRep :: forall (f :: * -> *) a p.
Representable f =>
f (a -> p) -> f a -> f p
distRep f (a -> p)
pr f a
fa = (Rep f -> p) -> f p
forall a. (Rep f -> a) -> f a
forall (f :: * -> *) a. Representable f => (Rep f -> a) -> f a
tabulate (\Rep f
r -> f (a -> p) -> Rep f -> a -> p
forall a. f a -> Rep f -> a
forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index f (a -> p)
pr Rep f
r (a -> p) -> a -> p
forall a b. (a -> b) -> a -> b
$ f a -> Rep f -> a
forall a. f a -> Rep f -> a
forall (f :: * -> *) a. Representable f => f a -> Rep f -> a
index f a
fa Rep f
r)
allTrue :: (Predicatory p, Foldable f) => f (a -> p) -> a -> p
allTrue :: forall p (f :: * -> *) a.
(Predicatory p, Foldable f) =>
f (a -> p) -> a -> p
allTrue f (a -> p)
ps a
a = ((a -> p) -> p -> p) -> p -> f (a -> p) -> p
forall a b. (a -> b -> b) -> b -> f a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\a -> p
p p
r -> a -> p
p a
a p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` p
r) p
forall a. Predicatory a => a
continue f (a -> p)
ps
allOf1 :: Predicatory p => Fold s a -> PT p a s
allOf1 :: forall p s a. Predicatory p => Fold s a -> PT p a s
allOf1 Fold s a
g a -> p
p s
vs =
p -> p -> Bool -> p
forall a. a -> a -> Bool -> a
bool p
forall a. Predicatory a => a
stop p
forall a. Predicatory a => a
continue (Getting Any s a -> s -> Bool
forall s a. Getting Any s a -> s -> Bool
notNullOf Getting Any s a
Fold s a
g s
vs)
p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` Getting (Endo p) s a -> (a -> p -> p) -> p -> s -> p
forall r s a. Getting (Endo r) s a -> (a -> r -> r) -> r -> s -> r
foldrOf Getting (Endo p) s a
Fold s a
g (\a
x p
r -> a -> p
p a
x p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` p
r) p
forall a. Predicatory a => a
continue s
vs
pattern a $m:=> :: forall {r} {a} {b}. (a, b) -> (a -> b -> r) -> ((# #) -> r) -> r
$b:=> :: forall {a} {b}. a -> b -> (a, b)
:=> b = (a, b)
pair :: Predicatory p => (a -> p) -> (b -> p) -> (a, b) -> p
pair :: forall p a b. Predicatory p => (a -> p) -> (b -> p) -> (a, b) -> p
pair a -> p
f b -> p
s (a
a, b
b) = a -> p
f a
a p -> p -> p
forall a. Predicatory a => a -> a -> a
`also` b -> p
s b
b
(!) :: (b -> a) -> (a -> c) -> b -> c
! :: forall b a c. (b -> a) -> (a -> c) -> b -> c
(!) = ((a -> c) -> (b -> a) -> b -> c) -> (b -> a) -> (a -> c) -> b -> c
forall a b c. (a -> b -> c) -> b -> a -> c
flip (a -> c) -> (b -> a) -> b -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
(.)
infixr 8 !
(?) :: (a -> b) -> a -> b
? :: forall a b. (a -> b) -> a -> b
(?) = (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
($)
infixl 9 ?
traced :: Show a => (a -> String) -> PT c a a
traced :: forall a c. Show a => (a -> String) -> PT c a a
traced a -> String
s a -> c
p a
a = String -> c -> c
forall a. String -> a -> a
trace (a -> String
s a
a) (a -> c
p a
a)
tracedShow :: Show a => PT c a a
tracedShow :: forall a c. Show a => PT c a a
tracedShow = (a -> String) -> PT c a a
forall a c. Show a => (a -> String) -> PT c a a
traced a -> String
forall a. Show a => a -> String
show
traceFailShow :: (Exceptional p, Predicatory p, Show a) => PT p a a
traceFailShow :: forall p a. (Exceptional p, Predicatory p, Show a) => PT p a a
traceFailShow = (a -> String) -> PT p a a
forall p a.
(Predicatory p, Exceptional p) =>
(a -> String) -> PT p a a
traceFail a -> String
forall a. Show a => a -> String
show
traceFail :: (Predicatory p, Exceptional p) => (a -> String) -> PT p a a
traceFail :: forall p a.
(Predicatory p, Exceptional p) =>
(a -> String) -> PT p a a
traceFail a -> String
s a -> p
p a
a =
p -> IO () -> p
forall a. Exceptional a => a -> IO () -> a
assess (a -> p
p a
a) (IO () -> p) -> IO () -> p
forall a b. (a -> b) -> a -> b
$ String -> IO ()
traceIO (a -> String
s a
a)
something :: Predicatory p => a -> p
something :: forall a e. Predicatory a => e -> a
something = p -> a -> p
forall a b. a -> b -> a
const p
forall a. Predicatory a => a
continue
forced :: (Predicatory p, NFData a) => a -> p
forced :: forall p a. (Predicatory p, NFData a) => a -> p
forced a
a = a -> a
forall a. NFData a => a -> a
force a
a a -> p -> p
forall a b. a -> b -> b
`seq` p
forall a. Predicatory a => a
continue
equals :: (Predicatory p, Eq a) => a -> a -> p
equals :: forall p a. (Predicatory p, Eq a) => a -> a -> p
equals a
a a
a' = p -> p -> Bool -> p
forall a. a -> a -> Bool -> a
bool p
forall a. Predicatory a => a
stop p
forall a. Predicatory a => a
continue (a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
a')
satAll :: Predicatory p => [a -> p] -> a -> p
satAll :: forall p a. Predicatory p => [a -> p] -> a -> p
satAll = ((a -> p) -> (a -> p) -> a -> p) -> (a -> p) -> [a -> p] -> a -> p
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (a -> p) -> (a -> p) -> a -> p
forall a. Predicatory a => a -> a -> a
also a -> p
forall a. Predicatory a => a
continue