packages feed

free-category 0.0.1.0 → 0.0.2.0

raw patch · 6 files changed

+125/−47 lines, 6 filesdep ~free-algebrassetup-changedPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: free-algebras

API changes (from Hackage documentation)

- Control.Category.Free: instance Control.Category.Category (Control.Category.Free.Cat f)
- Control.Category.Free: instance Data.Monoid.MSet.MSet (Control.Category.Free.Cat f o o) (Control.Category.Free.Cat f a o)
- Control.Category.Free: instance Data.Semigroup.SSet.SSet (Control.Category.Free.Cat f o o) (Control.Category.Free.Cat f a o)
- Control.Category.Free: instance GHC.Base.Monoid (Control.Category.Free.Cat f o o)
- Control.Category.Free: instance GHC.Base.Semigroup (Control.Category.Free.Cat f o o)
- Control.Category.Free: instance forall k (f :: k -> k -> *) (o :: k) (a :: k). Data.Monoid.MSet.MSet (Control.Category.Free.C f o o) (Control.Category.Free.C f a o)
- Control.Category.Free: instance forall k (f :: k -> k -> *) (o :: k) (a :: k). Data.Semigroup.SSet.SSet (Control.Category.Free.C f o o) (Control.Category.Free.C f a o)
+ Control.Category.Free: instance forall k (f :: k -> k -> *) (o :: k). GHC.Base.Monoid (Control.Category.Free.Cat f o o)
+ Control.Category.Free: instance forall k (f :: k -> k -> *) (o :: k). GHC.Base.Semigroup (Control.Category.Free.Cat f o o)
+ Control.Category.Free: instance forall k (f :: k -> k -> *). Control.Category.Category (Control.Category.Free.Cat f)
+ Control.Category.FreeEff: [Base] :: c a b -> FreeEffCat m c a b
+ Control.Category.FreeEff: [Lift] :: m (FreeEffCat m c a b) -> FreeEffCat m c a b
+ Control.Category.FreeEff: class Category c => EffCategory c m | c -> m
+ Control.Category.FreeEff: data FreeEffCat :: (* -> *) -> (k -> k -> *) -> k -> k -> *
+ Control.Category.FreeEff: foldNatLift :: (Monad m, EffCategory c m) => (forall x y. tr x y -> c x y) -> FreeEffCat m (Cat tr) a b -> c a b
+ Control.Category.FreeEff: instance Control.Category.FreeEff.EffCategory (->) Data.Functor.Identity.Identity
+ Control.Category.FreeEff: instance GHC.Base.Monad m => Control.Algebra.Free2.FreeAlgebra2 (Control.Category.FreeEff.FreeEffCat m)
+ Control.Category.FreeEff: instance GHC.Base.Monad m => Control.Category.FreeEff.EffCategory (Control.Arrow.Kleisli m) m
+ Control.Category.FreeEff: instance forall k (m :: * -> *) (c :: k -> k -> *). (GHC.Base.Functor m, Control.Category.Category c) => Control.Category.Category (Control.Category.FreeEff.FreeEffCat m c)
+ Control.Category.FreeEff: instance forall k (m :: * -> *) (c :: k -> k -> *). (GHC.Base.Functor m, Control.Category.Category c) => Control.Category.FreeEff.EffCategory (Control.Category.FreeEff.FreeEffCat m c) m
+ Control.Category.FreeEff: lift :: EffCategory c m => m (c a b) -> c a b
+ Control.Category.FreeEff: liftCat :: Monad m => tr a b -> FreeEffCat m (Cat tr) a b
+ Control.Category.FreeEff: liftKleisli :: Applicative m => (a -> b) -> Kleisli m a b
- Control.Arrow.Free: bindFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => m f a b -> (forall x y. () => f x y -> m g x y) -> m g a b
+ Control.Arrow.Free: bindFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => m f a b -> (forall (x :: k) (y :: k). () => f x y -> m g x y) -> m g a b
- Control.Arrow.Free: class FreeAlgebra2 (m :: Type -> Type -> Type -> Type -> Type -> Type)
+ Control.Arrow.Free: class FreeAlgebra2 (m :: k -> k -> Type -> k -> k -> Type)
- Control.Arrow.Free: foldNatFree2 :: (FreeAlgebra2 m, AlgebraType m d, AlgebraType0 m f) => (forall x y. () => f x y -> d x y) -> m f a b -> d a b
+ Control.Arrow.Free: foldNatFree2 :: (FreeAlgebra2 m, AlgebraType m d, AlgebraType0 m f) => (forall (x :: k) (y :: k). () => f x y -> d x y) -> m f a b -> d a b
- Control.Arrow.Free: hoistFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => (forall x y. () => f x y -> g x y) -> m f a b -> m g a b
+ Control.Arrow.Free: hoistFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => (forall (x :: k) (y :: k). () => f x y -> g x y) -> m f a b -> m g a b
- Control.Category.Free: bindFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => m f a b -> (forall x y. () => f x y -> m g x y) -> m g a b
+ Control.Category.Free: bindFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => m f a b -> (forall (x :: k) (y :: k). () => f x y -> m g x y) -> m g a b
- Control.Category.Free: class FreeAlgebra2 (m :: Type -> Type -> Type -> Type -> Type -> Type)
+ Control.Category.Free: class FreeAlgebra2 (m :: k -> k -> Type -> k -> k -> Type)
- Control.Category.Free: data Cat :: (* -> * -> *) -> * -> * -> *
+ Control.Category.Free: data Cat :: (k -> k -> *) -> k -> k -> *
- Control.Category.Free: foldNatFree2 :: (FreeAlgebra2 m, AlgebraType m d, AlgebraType0 m f) => (forall x y. () => f x y -> d x y) -> m f a b -> d a b
+ Control.Category.Free: foldNatFree2 :: (FreeAlgebra2 m, AlgebraType m d, AlgebraType0 m f) => (forall (x :: k) (y :: k). () => f x y -> d x y) -> m f a b -> d a b
- Control.Category.Free: hoistFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => (forall x y. () => f x y -> g x y) -> m f a b -> m g a b
+ Control.Category.Free: hoistFree2 :: (FreeAlgebra2 m, AlgebraType0 m g, AlgebraType0 m f) => (forall (x :: k) (y :: k). () => f x y -> g x y) -> m f a b -> m g a b

Files

ChangeLog.md view
@@ -1,5 +1,10 @@ # Changelog for free-category +## Version 0.0.2.0++- EffCategory class and FreeEffCat category transformer+- Example usage of FreeEffCat+ ## Version 0.0.1.0 - free category (concrete and condensity transformed) - free arrows (concrete and condensity transformed)
README.md view
@@ -1,13 +1,24 @@ # Free Category [![Maintainer: coot](https://img.shields.io/badge/maintainer-coot-lightgrey.svg)](http://github.com/coot)-[![Travis Build Status](https://travis-ci.org/coot/free-category.svg?branch=master)](https://travis-ci.org/coot/free-category)+[![CircleCI](https://circleci.com/gh/coot/free-category/tree/master.svg?style=svg)](https://circleci.com/gh/coot/free-category/tree/master) -This package introduces variouos encodings of free categories in Haskell.+This package introduces variouos presentations of free categories in Haskell.  Free categories are useful to model state machines in a simple yet type safe way and for that purpose `Kleisli` categroies are a very useful target which-allows to include monadic computations.  Read more-[here](https://coot.me/posts/finite-state-machines.html) on a simple example of-a finite state machine encoded using a free category using a simple GADT.-Another simple-[example](https://github.com/coot/free-algebras/blob/master/examples/src/Control/Category/Free.hs).+allows to include monadic computations.  This packge contains a useful+generalisation of `Kliesli` categories captured by `EffCategory` class+(effectful categories), and a (free) transformer which lifts a category to+an effectful one.++## Some examples+* [LoginStateMachine](https://github.com/coot/free-category/blob/master/examples/src/LoginStateMachine.hs):+  based on [State Machines All The Way+  Down](https://www.youtube.com/watch?v=xq7ZuSRgCR4) by Edwin Bradly, 2017 You+  can run it with `cabal new-run examples:login-state-machine`.+* Read more [here](https://coot.me/posts/finite-state-machines.html) on+  a simple example of a finite state machine encoded using a free category+  using a simple GADT.+* Another+  [example](https://github.com/coot/free-algebras/blob/master/examples/src/Control/Category/Free.hs).+* [Blog post](https://coot.me/posts/kleisli-categories-and-free-monads.html) on Keleisli categories.
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
free-category.cabal view
@@ -1,5 +1,5 @@ name:           free-category-version:        0.0.1.0+version:        0.0.2.0 synopsis:       Free category description:    Free categories category:       Algebra, Control, Monads, Category@@ -24,31 +24,32 @@   exposed-modules:       Control.Arrow.Free       Control.Category.Free+      Control.Category.FreeEff   other-modules:       Paths_free_category   hs-source-dirs:       src   default-extensions:-    ConstraintKinds-    DataKinds-    DeriveFunctor-    EmptyDataDecls-    FlexibleInstances-    FlexibleContexts-    GADTs-    KindSignatures-    InstanceSigs-    MultiParamTypeClasses-    OverloadedStrings-    PolyKinds-    RankNTypes-    ScopedTypeVariables-    TupleSections-    TypeApplications-    TypeFamilies+      ConstraintKinds+      DataKinds+      DeriveFunctor+      EmptyDataDecls+      FlexibleInstances+      FlexibleContexts+      GADTs+      KindSignatures+      InstanceSigs+      MultiParamTypeClasses+      OverloadedStrings+      PolyKinds+      RankNTypes+      ScopedTypeVariables+      TupleSections+      TypeApplications+      TypeFamilies   build-depends:       base          >= 4.9 && <5-    , free-algebras >= 0.0.6.0+    , free-algebras >= 0.0.7.0   ghc-options:     -Wall     -fwarn-incomplete-record-updates
src/Control/Category/Free.hs view
@@ -37,8 +37,6 @@ import           Data.Monoid (Monoid (..)) import           Data.Semigroup (Semigroup (..)) #endif-import           Data.Monoid.MSet (MSet (..))-import           Data.Semigroup.SSet (SSet (..))  -- | -- Free category encoded as a recursive data type, in a simlar way as@@ -49,7 +47,7 @@ -- -- The same performance concerns that apply to @'Control.Monad.Free.Free'@ -- apply to this encoding of a free category.-data Cat :: (* -> * -> *) -> * -> * -> * where+data Cat :: (k -> k -> *) -> k -> k -> * where   Id    :: Cat f a a   (:.:) :: f b c -> Cat f a b -> Cat f a c @@ -86,14 +84,6 @@   mappend = (<>) #endif -instance SSet (Cat f o o) (Cat f a o) where-  act = (.)--instance MSet (Cat f o o) (Cat f a o) where-#if __GLASGOW_HASKELL__ < 804-  mact = (.)-#endif- type instance AlgebraType0 Cat f = () type instance AlgebraType  Cat c = Category c @@ -167,12 +157,4 @@   mempty = id #if __GLASGOW_HASKELL__ < 804   mappend = (<>)-#endif--instance SSet (C f o o) (C f a o) where-  act = (.)--instance MSet (C f o o) (C f a o) where-#if __GLASGOW_HASKELL__ < 804-  mact = (.) #endif
+ src/Control/Category/FreeEff.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE FunctionalDependencies #-}+module Control.Category.FreeEff+  ( EffCategory (..)+  , FreeEffCat (..)+  , liftCat+  , foldNatLift+  , liftKleisli+  ) where++import Prelude hiding (id, (.))++import Control.Arrow (Kleisli (..))+import Control.Category (Category (..))+import Data.Functor.Identity (Identity (..))++import Control.Category.Free (Cat (..))+import Control.Algebra.Free2 (FreeAlgebra2 (..))+import Data.Algebra.Free (AlgebraType, AlgebraType0, proof)+++-- | Categories which can lift monadic actions, i.e. effectful categories.+--+class Category c => EffCategory c m | c -> m where+  lift :: m (c a b) -> c a b++instance Monad m => EffCategory (Kleisli m) m where+  lift m = Kleisli (\a -> m >>= \(Kleisli f) -> f a)++instance EffCategory (->) Identity where+  lift = runIdentity++-- | Category transformer, which adds @'EffCategory'@ instance to the+-- underlying base category.+--+data FreeEffCat :: (* -> *) -> (k -> k -> *) -> k -> k -> * where+  Base :: c a b -> FreeEffCat m c a b+  Lift :: m (FreeEffCat m c a b) -> FreeEffCat m c a b++instance (Functor m, Category c) => Category (FreeEffCat m c) where+  id = Base id+  Base f  . Base g  = Base $ f . g+  f       . Lift mg = Lift $ (f .) <$> mg+  Lift mf . g       = Lift $ (. g) <$> mf++instance (Functor m, Category c) => EffCategory (FreeEffCat m c) m where+  lift = Lift++type instance AlgebraType0 (FreeEffCat m) c = (Monad m, Category c)+type instance AlgebraType  (FreeEffCat m) c  = EffCategory c m+instance Monad m => FreeAlgebra2 (FreeEffCat m) where+  liftFree2    = Base+  foldNatFree2 nat (Base cab)  = nat cab+  foldNatFree2 nat (Lift mcab) = lift $ foldNatFree2 nat <$> mcab++  codom2  = proof+  forget2 = proof++-- | Wrap a transition into a free category @'Cat'@ and then in+-- @'FreeEffCat'@+--+-- prop> liftCat tr = Base (tr :.: Id)+--+liftCat :: Monad m => tr a b -> FreeEffCat m (Cat tr) a b+liftCat = liftFree2 . liftFree2++-- | Fold @'FreeLifing'@ category based on a free category @'Cat' tr@ using+-- a functor @tr x y -> c x y@.+--+foldNatLift+  :: (Monad m, EffCategory c m)+  => (forall x y. tr x y -> c x y)+  -> FreeEffCat m (Cat tr) a b+  -> c a b+foldNatLift nat = foldNatFree2 (foldNatFree2 nat)++-- |  Functor from @'->'@ category to @'Kleisli' m@.  If @m@ is @Identity@ then+-- it will respect @'lift'@ i.e. @liftKleisli (lift ar) = lift (liftKleisli <$>+-- ar).+--+liftKleisli :: Applicative m => (a -> b) -> Kleisli m a b+liftKleisli f = Kleisli (pure . f)