packages feed

monad-skeleton 0.1.2 → 0.1.2.1

raw patch · 2 files changed

+28/−5 lines, 2 filesPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

API changes (from Hackage documentation)

+ Control.Monad.Skeleton: debone :: Skeleton t a -> MonadView t (Skeleton t) a
+ Control.Monad.Skeleton: instance Functor m => Functor (MonadView t m)

Files

monad-skeleton.cabal view
@@ -1,5 +1,5 @@ name:                monad-skeleton
-version:             0.1.2
+version:             0.1.2.1
 synopsis:            An undead monad
 description:         A simple operational monad based on Reflection without Remorse
 homepage:            https://github.com/fumieval/monad-skeleton
src/Control/Monad/Skeleton.hs view
@@ -4,6 +4,7 @@   , iterMV   , Skeleton   , bone+  , debone   , unbone   , boned   , hoistSkeleton) where@@ -16,22 +17,31 @@ import GHC.Prim import Prelude hiding (id, (.)) +-- | Re-add a bone. boned :: MonadView t (Skeleton t) a -> Skeleton t a boned t = Skeleton t id {-# INLINE boned #-} -unbone :: Skeleton t a -> MonadView t (Skeleton t) a-unbone (Skeleton (Return a) s) = case viewL s of+-- | Pick a bone from a 'Skeleton'.+debone :: Skeleton t a -> MonadView t (Skeleton t) a+debone (Skeleton (Return a) s) = case viewL s of   Empty -> Return a   Kleisli k :| c -> case k a of-    Skeleton h t -> unbone $ Skeleton h (c . t)-unbone (Skeleton (t :>>= k) s) = t :>>= \a -> case k a of+    Skeleton h t -> debone $ Skeleton h (c . t)+debone (Skeleton (t :>>= k) s) = t :>>= \a -> case k a of   Skeleton h t -> Skeleton h (s . t) +-- | Uncommon synonym for 'debone'.+unbone :: Skeleton t a -> MonadView t (Skeleton t) a+unbone = debone+{-# INLINE unbone #-}++-- | A skeleton that has only one bone. bone :: t a -> Skeleton t a bone t = Skeleton (t :>>= return) id {-# INLINABLE bone #-} +-- | Lift a transformation between bones into transformation between skeletons. hoistSkeleton :: (forall x. s x -> t x) -> Skeleton s a -> Skeleton t a hoistSkeleton f (Skeleton v c) = Skeleton (hoistMV f (hoistSkeleton f) v)   (transCat (transKleisli (hoistSkeleton f)) c)@@ -41,16 +51,28 @@   (:>>=) :: t a -> (a -> m b) -> MonadView t m b infixl 1 :>>= +instance Functor m => Functor (MonadView t m) where+  fmap f (Return a) = Return (f a)+  fmap f (t :>>= k) = t :>>= fmap f . k+  {-# INLINE fmap #-}+ hoistMV :: (forall x. s x -> t x) -> (m a -> n a) -> MonadView s m a -> MonadView t n a hoistMV _ _ (Return a) = Return a hoistMV f g (t :>>= k) = f t :>>= g . k+{-# INLINE hoistMV #-}  iterMV :: Monad m => (t a -> MonadView m t a) -> t a -> m a iterMV f = go where   go t = case f t of     m :>>= k -> m >>= go . k     Return a -> return a+{-# INLINE iterMV #-} +-- | @'Skeleton' t@ is a monadic skeleton (operational monad) made out of 't'.+-- Skeletons can be fleshed out by getting transformed to other monads.+-- The implementation is based on+-- <http://wwwhome.cs.utwente.nl/~jankuper/fp-dag/pref.pdf Reflection without Remorse>+-- so it provides efficient ('>>=') and 'debone', monadic reflection. data Skeleton t a where   Skeleton :: MonadView t (Skeleton t) x -> Cat (Kleisli (Skeleton t)) x a -> Skeleton t a @@ -76,6 +98,7 @@ viewL (Cat s) = case Seq.viewl s of   Seq.EmptyL -> unsafeCoerce Empty   a Seq.:< b -> unsafeCoerce (:|) a b+{-# INLINE viewL #-}  instance Category (Cat k) where   id = Cat Seq.empty