module Data.Fold.M
( M(..)
) where
import Control.Applicative
import Control.Comonad
import Control.Lens
import Control.Monad.Zip
import Data.Fold.Class
import Data.Fold.Internal
import Data.Foldable hiding (sum, product)
import Data.Functor.Extend
import Data.Functor.Bind
import Data.Profunctor.Unsafe
import Data.Proxy
import Data.Reflection
import Unsafe.Coerce
import Prelude hiding (sum, product, length)
data M a b = forall m. M (m -> b) (a -> m) (m -> m -> m) m
instance Scan M where
run1 a (M k h _ _) = k (h a)
prefix1 a (M k h m z) = case h a of
x -> M (\y -> k (m x y)) h m z
postfix1 (M k h m z) a = case h a of
y -> M (\x -> k (m x y)) h m z
interspersing a (M k h m z) = M (maybe' (k z) k) h' m' Nothing' where
h' r = Just' (h r)
m' (Just' x) (Just' y) = Just' (x `m` h a `m` y)
m' Nothing' my = my
m' mx Nothing' = mx
instance Folding M where
run s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> k $ runN (foldMap (N #. h) s :: N m s)
runOf l s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> k $ runN (foldMapOf l (N #. h) s :: N m s)
prefix s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMap (N #. h) s :: N m s) of
x -> M (\y -> k (m x y)) h m z
prefixOf l s (M k h m (z :: m)) = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMapOf l (N #. h) s :: N m s) of
x -> M (\y -> k (m x y)) h m z
postfix (M k h m (z :: m)) s = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMap (N #. h) s :: N m s) of
y -> M (\x -> k (m x y)) h m z
postfixOf l (M k h m (z :: m)) s = reify (m, z) $
\ (_ :: Proxy s) -> case runN (foldMapOf l (N #. h) s :: N m s) of
y -> M (\x -> k (m x y)) h m z
filtering p (M k h m z) = M k (\a -> if p a then h a else z) m z
instance Profunctor M where
dimap f g (M k h m e) = M (g.k) (h.f) m e
rmap g (M k h m e) = M (g.k) h m e
lmap f (M k h m e) = M k (h.f) m e
(#.) _ = unsafeCoerce
x .# _ = unsafeCoerce x
instance Choice M where
left' (M k h m z) = M (_Left %~ k) (_Left %~ h) step (Left z) where
step (Left x) (Left y) = Left (m x y)
step (Right c) _ = Right c
step _ (Right c) = Right c
right' (M k h m z) = M (_Right %~ k) (_Right %~ h) step (Right z) where
step (Right x) (Right y) = Right (m x y)
step (Left c) _ = Left c
step _ (Left c) = Left c
instance Functor (M a) where
fmap f (M k h m z) = M (f.k) h m z
(<$) b = \_ -> pure b
instance Comonad (M a) where
extract (M k _ _ z) = k z
duplicate (M k h m z) = M (\n -> M (k . m n) h m z) h m z
instance Applicative (M a) where
pure b = M (\() -> b) (\_ -> ()) (\() () -> ()) ()
M xf bx xx xz <*> M ya by yy yz = M
(\(Pair' x y) -> xf x $ ya y)
(\b -> Pair' (bx b) (by b))
(\(Pair' x1 y1) (Pair' x2 y2) -> Pair' (xx x1 x2) (yy y1 y2))
(Pair' xz yz)
(<*) m = \_ -> m
_ *> m = m
instance Bind (M a) where
(>>-) = (>>=)
instance Monad (M a) where
return = pure
m >>= f = M (\xs a -> run xs (f a)) One Two Zero <*> m
_ >> n = n
instance MonadZip (M a) where
mzipWith = liftA2
instance Extend (M a) where
extended = extend
duplicated = duplicate
instance Apply (M a) where
(<.>) = (<*>)
(<.) m = \_ -> m
_ .> m = m
instance ComonadApply (M a) where
(<@>) = (<*>)
(<@) m = \_ -> m
_ @> m = m