module Data.Fold.L1'
( L1'(..)
) where
import Control.Applicative
import Control.Arrow
import Control.Category
import Control.Lens
import Data.Fold.Class
import Data.Fold.Internal
import Data.Functor.Apply
import Data.Pointed
import Data.Profunctor
import Data.Profunctor.Unsafe
import Data.Semigroupoid
import Prelude hiding (id,(.))
import Unsafe.Coerce
data L1' a b = forall c. L1' (c -> b) (c -> a -> c) (a -> c)
instance Scan L1' where
run1 a (L1' k _ z) = k (z a)
prefix1 a (L1' k h z) = L1' k h (h $! z a)
postfix1 (L1' k h z) a = L1' (\c -> k $! h c a) h z
interspersing a (L1' k h z) = L1' k (\x b -> (h $! h x a) b) z
instance Functor (L1' a) where
fmap f (L1' k h z) = L1' (f.k) h z
b <$ _ = pure b
instance Pointed (L1' a) where
point x = L1' (\() -> x) (\() _ -> ()) (\_ -> ())
instance Apply (L1' a) where
(<.>) = (<*>)
(<.) m = \_ -> m
_ .> m = m
instance Applicative (L1' a) where
pure x = L1' (\() -> x) (\() _ -> ()) (\_ -> ())
L1' kf hf zf <*> L1' ka ha za = L1'
(\(Pair' x y) -> kf x (ka y))
(\(Pair' x y) a -> Pair' (hf x a) (ha y a))
(\a -> Pair' (zf a) (za a))
(<*) m = \ _ -> m
_ *> m = m
instance Monad (L1' a) where
return x = L1' (\() -> x) (\() _ -> ()) (\_ -> ())
m >>= f = L1' (\xs a -> walk xs (f a)) Snoc1 First <*> m where
_ >> n = n
instance Semigroupoid L1' where
o = (.)
instance Category L1' where
id = arr id
L1' k h z . L1' k' h' z' = L1' (\(Pair' b _) -> k b) h'' z'' where
z'' a = Pair' (z (k' b)) b where b = z' a
h'' (Pair' c d) a = Pair' (h c (k' d')) d' where d' = h' d a
instance Arrow L1' where
arr h = L1' h (\_ a -> a) id
first (L1' k h z) = L1' (first k) h' (first z) where
h' (a,_) (c,b) = (h a c, b)
second (L1' k h z) = L1' (second k) h' (second z) where
h' (_,b) (a,c) = (a, h b c)
L1' k h z *** L1' k' h' z' = L1' (k *** k') h'' (z *** z') where
h'' (a,b) (c,d) = (h a c, h' b d)
L1' k h z &&& L1' k' h' z' = L1' (k *** k') h'' (z &&& z') where
h'' (c,d) a = (h c a, h' d a)
instance Profunctor L1' where
dimap f g (L1' k h z) = L1' (g.k) (\a -> h a . f) (z.f)
lmap f (L1' k h z) = L1' (k) (\a -> h a . f) (z.f)
rmap g (L1' k h z) = L1' (g.k) h z
( #. ) _ = unsafeCoerce
x .# _ = unsafeCoerce x
instance Strong L1' where
first' = first
second' = second
instance Choice L1' where
left' (L1' k h z) = L1' (_Left %~ k) step (_Left %~ z) where
step (Left x) (Left y) = Left (h x y)
step (Right c) _ = Right c
step _ (Right c) = Right c
right' (L1' k h z) = L1' (_Right %~ k) step (_Right %~ z) where
step (Right x) (Right y) = Right (h x y)
step (Left c) _ = Left c
step _ (Left c) = Left c
instance ArrowChoice L1' where
left (L1' k h z) = L1' (_Left %~ k) step (_Left %~ z) where
step (Left x) (Left y) = Left (h x y)
step (Right c) _ = Right c
step _ (Right c) = Right c
right (L1' k h z) = L1' (_Right %~ k) step (_Right %~ z) where
step (Right x) (Right y) = Right (h x y)
step (Left c) _ = Left c
step _ (Left c) = Left c
walk :: SnocList1 a -> L1' a b -> b
walk xs0 (L1' k h z) = k (go xs0) where
go (First a) = z a
go (Snoc1 as a) = h (go as) a