free 3.4.1 → 3.4.2
raw patch · 8 files changed
+83/−25 lines, 8 filesdep +profunctorsPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: profunctors
API changes (from Hackage documentation)
+ Control.Comonad.Trans.Cofree: coiterT :: (Functor f, Comonad w) => (w a -> f (w a)) -> w a -> CofreeT f w a
+ Control.Monad.Free: _Free :: (Choice p, Applicative m) => p (f (Free f a)) (m (f (Free f a))) -> p (Free f a) (m (Free f a))
+ Control.Monad.Free: _Pure :: (Choice p, Applicative m) => p a (m a) -> p (Free f a) (m (Free f a))
+ Control.Monad.Free: iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> Free f a -> m a
+ Control.Monad.Free.Church: class Monad m => MonadFree f m | m -> f
+ Control.Monad.Free.Church: iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> F f a -> m a
+ Control.Monad.Free.Church: wrap :: MonadFree f m => f (m a) -> m a
+ Control.Monad.Free.Class: liftF :: (Functor f, MonadFree f m) => f a -> m a
+ Control.Monad.Trans.Free: iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> FreeT f m a -> m a
+ Control.MonadPlus.Free: iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> ([m a] -> m a) -> Free f a -> m a
- Control.Monad.Free: liftF :: Functor f => f a -> Free f a
+ Control.Monad.Free: liftF :: (Functor f, MonadFree f m) => f a -> m a
- Control.Monad.Free.Church: liftF :: Functor f => f a -> F f a
+ Control.Monad.Free.Church: liftF :: (Functor f, MonadFree f m) => f a -> m a
- Control.Monad.Trans.Free: liftF :: (Functor f, Monad m) => f a -> FreeT f m a
+ Control.Monad.Trans.Free: liftF :: (Functor f, MonadFree f m) => f a -> m a
- Control.MonadPlus.Free: liftF :: Functor f => f a -> Free f a
+ Control.MonadPlus.Free: liftF :: (Functor f, MonadFree f m) => f a -> m a
Files
- CHANGELOG.markdown +5/−0
- free.cabal +3/−2
- src/Control/Comonad/Trans/Cofree.hs +5/−0
- src/Control/Monad/Free.hs +41/−5
- src/Control/Monad/Free/Church.hs +8/−7
- src/Control/Monad/Free/Class.hs +5/−0
- src/Control/Monad/Trans/Free.hs +8/−6
- src/Control/MonadPlus/Free.hs +8/−5
CHANGELOG.markdown view
@@ -1,3 +1,8 @@+3.4.2+-----+* Generalized `liftF`.+* Added `iterM`+ 3.4.1 ----- * Added support for GHC 7.7's polykinded `Typeable`
free.cabal view
@@ -1,6 +1,6 @@ name: free category: Control, Monads-version: 3.4.1+version: 3.4.2 license: BSD3 cabal-version: >= 1.10 license-file: LICENSE@@ -61,7 +61,8 @@ comonad >= 3, comonad-transformers >= 3, comonads-fd >= 3,- semigroups >= 0.8.3.1+ semigroups >= 0.8.3.1,+ profunctors >= 3.2 && < 4 if impl(ghc) cpp-options: -DGHC_TYPEABLE
src/Control/Comonad/Trans/Cofree.hs view
@@ -25,6 +25,7 @@ , ComonadCofree(..) , headF , tailF+ , coiterT ) where import Control.Applicative@@ -115,6 +116,10 @@ instance Ord (w (CofreeF f a (CofreeT f w a))) => Ord (CofreeT f w a) where compare (CofreeT a) (CofreeT b) = compare a b++-- | Unfold a @CofreeT@ comonad transformer from a coalgebra and an initial comonad.+coiterT :: (Functor f, Comonad w) => (w a -> f (w a)) -> w a -> CofreeT f w a+coiterT psi = CofreeT . (extend $ \w -> extract w :< fmap (coiterT psi) (psi w)) #if defined(GHC_TYPEABLE) && __GLASGOW_HASKELL__ < 707
src/Control/Monad/Free.hs view
@@ -25,7 +25,9 @@ , retract , liftF , iter+ , iterM , hoistFree+ , _Pure, _Free ) where import Control.Applicative@@ -39,6 +41,7 @@ import Control.Monad.Cont.Class import Data.Functor.Bind import Data.Foldable+import Data.Profunctor import Data.Traversable import Data.Semigroup.Foldable import Data.Semigroup.Traversable@@ -224,11 +227,6 @@ callCC f = lift (callCC (retract . f . liftM lift)) {-# INLINE callCC #-} --- | A version of 'lift' that can be used with just a 'Functor' for @f@.-liftF :: Functor f => f a -> Free f a-liftF = Free . fmap Pure-{-# INLINE liftF #-}- instance Functor f => MonadFree f (Free f) where wrap = Free {-# INLINE wrap #-}@@ -249,10 +247,48 @@ iter _ (Pure a) = a iter phi (Free m) = phi (iter phi <$> m) +-- | Like iter for monadic values.+iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> Free f a -> m a+iterM _ (Pure x) = return x+iterM phi (Free f) = phi $ fmap (iterM phi) f+ -- | Lift a natural transformation from @f@ to @g@ into a natural transformation from @'FreeT' f@ to @'FreeT' g@. hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b hoistFree _ (Pure a) = Pure a hoistFree f (Free as) = Free (hoistFree f <$> f as)++-- | This is @Prism' (Free f a) a@ in disguise+--+-- >>> preview _Pure (Pure 3)+-- Just 3+--+-- >>> review _Pure 3 :: Free Maybe Int+-- Pure 3+_Pure :: forall f m a p. (Choice p, Applicative m)+ => p a (m a) -> p (Free f a) (m (Free f a))+_Pure = dimap impure (either pure (fmap Pure)) . right'+ where+ impure (Pure x) = Right x+ impure x = Left x+ {-# INLINE impure #-}+{-# INLINE _Pure #-}++-- | This is @Prism' (Free f a) (f (Free f a))@ in disguise+--+-- >>> preview _Free (review _Free (Just (Pure 3)))+-- Just (Just (Pure 3))+--+-- >>> review _Free (Just (Pure 3))+-- Free (Just (Pure 3))+_Free :: forall f m a p. (Choice p, Applicative m)+ => p (f (Free f a)) (m (f (Free f a))) -> p (Free f a) (m (Free f a))+_Free = dimap unfree (either pure (fmap Free)) . right'+ where+ unfree (Free x) = Right x+ unfree x = Left x+ {-# INLINE unfree #-}+{-# INLINE _Free #-}+ #if defined(GHC_TYPEABLE) && __GLASGOW_HASKELL__ < 707 instance Typeable1 f => Typeable1 (Free f) where
src/Control/Monad/Free/Church.hs view
@@ -23,14 +23,16 @@ ( F(..) , improve , fromF+ , iterM , toF- , liftF , retract+ , MonadFree(..)+ , liftF ) where import Control.Applicative import Control.Monad as Monad-import Control.Monad.Free hiding (liftF, retract)+import Control.Monad.Free hiding (retract, iterM) import Control.Monad.Reader.Class import Control.Monad.Writer.Class import Control.Monad.Cont.Class@@ -45,6 +47,10 @@ -- <http://comonad.com/reader/2011/free-monads-for-less-2/> newtype F f a = F { runF :: forall r. (a -> r) -> (f r -> r) -> r } +-- | Like iter for monadic values.+iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> F f a -> m a+iterM phi xs = runF xs return phi+ instance Functor (F f) where fmap f (F g) = F (\kp -> g (kp . f)) @@ -91,11 +97,6 @@ instance MonadCont m => MonadCont (F m) where callCC f = lift $ callCC (retract . f . fmap lift)---- | A version of 'lift' that can be used with just a 'Functor' for @f@.-liftF :: Functor f => f a -> F f a-liftF f = F (\kp kf -> kf (fmap kp f))-{-# INLINE liftF #-} -- | -- 'retract' is the left inverse of 'lift' and 'liftF'
src/Control/Monad/Free/Class.hs view
@@ -16,6 +16,7 @@ ---------------------------------------------------------------------------- module Control.Monad.Free.Class ( MonadFree(..)+ , liftF ) where import Control.Applicative@@ -116,3 +117,7 @@ instance (Functor f, MonadFree f m, Error e) => MonadFree f (ErrorT e m) where wrap = ErrorT . wrap . fmap runErrorT++-- | A version of lift that can be used with just a Functor for f.+liftF :: (Functor f, MonadFree f m) => f a -> m a+liftF = wrap . fmap return
src/Control/Monad/Trans/Free.hs view
@@ -25,6 +25,7 @@ , FreeT(..) , MonadFree(..) , liftF+ , iterT , hoistFreeT , transFreeT ) where@@ -139,12 +140,13 @@ wrap = FreeT . return . Free {-# INLINE wrap #-} --- | FreeT is a functor from the category of functors to the category of monads.------ This provides the mapping.-liftF :: (Functor f, Monad m) => f a -> FreeT f m a-liftF = wrap . fmap return-{-# INLINE liftF #-}+-- | Tear down a free monad transformer using iteration.+iterT :: (Functor f, Monad m) => (f (m a) -> m a) -> FreeT f m a -> m a+iterT f (FreeT m) = do+ val <- m+ case fmap (iterT f) val of+ Pure x -> return x+ Free y -> f y instance (Foldable m, Foldable f) => Foldable (FreeT f m) where foldMap f (FreeT m) = foldMap (bifoldMap f (foldMap f)) m
src/Control/MonadPlus/Free.hs view
@@ -25,6 +25,7 @@ , retract , liftF , iter+ , iterM , hoistFree ) where @@ -220,11 +221,6 @@ callCC f = lift (callCC (retract . f . liftM lift)) {-# INLINE callCC #-} --- | A version of 'lift' that can be used with just a 'Functor' for @f@.-liftF :: Functor f => f a -> Free f a-liftF = Free . fmap Pure-{-# INLINE liftF #-}- instance Functor f => MonadFree f (Free f) where wrap = Free {-# INLINE wrap #-}@@ -248,6 +244,13 @@ go (Free as) = phi (go <$> as) go (Plus as) = psi (go <$> as) {-# INLINE iter #-}++-- | Like iter for monadic values.+iterM :: (Monad m, Functor f) => (f (m a) -> m a) -> ([m a] -> m a) -> Free f a -> m a+iterM phi psi = go where+ go (Pure a) = return a+ go (Free as) = phi (go <$> as)+ go (Plus as) = psi (go <$> as) -- | Lift a natural transformation from @f@ to @g@ into a natural transformation from @'FreeT' f@ to @'FreeT' g@. hoistFree :: Functor g => (forall a. f a -> g a) -> Free f b -> Free g b