diff --git a/Gruntfile.js b/Gruntfile.js index 51c97b1f..e44d9033 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -16,40 +16,52 @@ module.exports = function(grunt) { pscDocs: { trans: { src: "src/Control/Monad/Trans.purs", - dest: "docs/Trans.md" + dest: "docs/Monad/Trans.md" }, cont: { src: "src/Control/Monad/Cont/*.purs", - dest: "docs/Cont.md" + dest: "docs/Monad/Cont.md" }, error: { src: ["src/Control/Monad/Error/*.purs", "src/Control/Monad/Error.purs"], - dest: "docs/Error.md" + dest: "docs/Monad/Error.md" }, maybe: { src: "src/Control/Monad/Maybe/*.purs", - dest: "docs/Maybe.md" + dest: "docs/Monad/Maybe.md" }, reader: { src: ["src/Control/Monad/Reader/*.purs", "src/Control/Monad/Reader.purs"], - dest: "docs/Reader.md" + dest: "docs/Monad/Reader.md" }, rws: { src: ["src/Control/Monad/RWS/*.purs", "src/Control/Monad/RWS.purs"], - dest: "docs/RWS.md" + dest: "docs/Monad/RWS.md" }, state: { src: ["src/Control/Monad/State/*.purs", "src/Control/Monad/State.purs"], - dest: "docs/State.md" + dest: "docs/Monad/State.md" }, writer: { src: ["src/Control/Monad/Writer/*.purs", "src/Control/Writer/Reader.purs"], - dest: "docs/Writer.md" + dest: "docs/Monad/Writer.md" + }, + cotrans: { + src: "src/Control/Comonad/Trans.purs", + dest: "docs/Comonad/Trans.md" + }, + env: { + src: ["src/Control/Comonad/Env/*.purs", "src/Control/Comonad/Env.purs"], + dest: "docs/Comonad/Env.md" + }, + store: { + src: ["src/Control/Comonad/Store/*.purs", "src/Control/Comonad/Store.purs"], + dest: "docs/Comonad/Store.md" + }, + traced: { + src: ["src/Control/Comonad/Traced/*.purs", "src/Control/Comonad/Traced.purs"], + dest: "docs/Comonad/Traced.md" }, - comonads: { - src: "src/Control/Comonad/**/*.purs", - dest: "docs/Comonad.md" - } }, psc: { diff --git a/README.md b/README.md index 959c864c..1be62d8f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,26 @@ purescript-transformers [![Build Status](https://travis-ci.org/purescript/purescript-transformers.svg?branch=master)](https://travis-ci.org/purescript/purescript-transformers) -Monad transformers based on [mtl](http://hackage.haskell.org/package/mtl). +Monad and comonad transformers based on [mtl](http://hackage.haskell.org/package/mtl). -- [Module documentation](docs/) - [Examples](examples/) + +## Documentation + +### Monad Transformers + +- [MonadTrans](docs/Monad/Trans.md) +- [Errors](docs/Monad/Error.md) +- [Maybe](docs/Monad/Maybe.md) +- [State](docs/Monad/State.md) +- [Writer](docs/Monad/Writer.md) +- [Reader](docs/Monad/Reader.md) +- [Reader/Writer/State](docs/Monad/RWS.md) +- [CPS](docs/Monad/Cont.md) + +### Comonad Transformers + +- [ComonadTrans](docs/Comonad/Trans.md) +- [Environment](docs/Comonad/Env.md) +- [Store](docs/Comonad/Store.md) +- [Cowriter](docs/Comonad/Traced.md) \ No newline at end of file diff --git a/docs/Comonad.md b/docs/Comonad.md deleted file mode 100644 index acb3c478..00000000 --- a/docs/Comonad.md +++ /dev/null @@ -1,374 +0,0 @@ -# Module Documentation - -## Module Control.Comonad.Env - -#### `Env` - -``` purescript -type Env e = EnvT e Identity -``` - - -#### `runEnv` - -``` purescript -runEnv :: forall e a. Env e a -> Tuple e a -``` - - -#### `withEnv` - -``` purescript -withEnv :: forall e1 e2 a. (e1 -> e2) -> Env e1 a -> Env e2 a -``` - - -#### `mapEnv` - -``` purescript -mapEnv :: forall e a b. (a -> b) -> Env e a -> Env e b -``` - - -#### `env` - -``` purescript -env :: forall e a. e -> a -> Env e a -``` - - - -## Module Control.Comonad.Env.Class - -#### `ComonadEnv` - -``` purescript -class (Comonad w) <= ComonadEnv e w where - ask :: forall a. w a -> e - local :: forall a. (e -> e) -> w a -> w a -``` - - -#### `comonadEnvTuple` - -``` purescript -instance comonadEnvTuple :: ComonadEnv e (Tuple e) -``` - - -#### `comonadEnvEnvT` - -``` purescript -instance comonadEnvEnvT :: (Comonad w) => ComonadEnv e (EnvT e w) -``` - - -#### `asks` - -``` purescript -asks :: forall e1 e2 w a. (ComonadEnv e1 w) => (e1 -> e2) -> w e1 -> e2 -``` - - - -## Module Control.Comonad.Env.Trans - -#### `EnvT` - -``` purescript -newtype EnvT e w a - = EnvT (Tuple e (w a)) -``` - - -#### `runEnvT` - -``` purescript -runEnvT :: forall e w a. EnvT e w a -> Tuple e (w a) -``` - - -#### `withEnvT` - -``` purescript -withEnvT :: forall e1 e2 w a. (e1 -> e2) -> EnvT e1 w a -> EnvT e2 w a -``` - - -#### `mapEnvT` - -``` purescript -mapEnvT :: forall e w1 w2 a b. (w1 a -> w2 b) -> EnvT e w1 a -> EnvT e w2 b -``` - - -#### `functorEnvT` - -``` purescript -instance functorEnvT :: (Functor w) => Functor (EnvT e w) -``` - - -#### `extendEnvT` - -``` purescript -instance extendEnvT :: (Extend w) => Extend (EnvT e w) -``` - - -#### `comonadEnvT` - -``` purescript -instance comonadEnvT :: (Comonad w) => Comonad (EnvT e w) -``` - - -#### `comonadTransEnvT` - -``` purescript -instance comonadTransEnvT :: ComonadTrans (EnvT e) -``` - - - -## Module Control.Comonad.Store - -#### `Store` - -``` purescript -type Store s a = StoreT s Identity a -``` - - -#### `runStore` - -``` purescript -runStore :: forall s a. Store s a -> Tuple (s -> a) s -``` - - -#### `store` - -``` purescript -store :: forall s a. (s -> a) -> s -> Store s a -``` - - - -## Module Control.Comonad.Store.Class - -#### `ComonadStore` - -``` purescript -class (Comonad w) <= ComonadStore s w where - pos :: forall a. w a -> s - peek :: forall a. s -> w a -> a -``` - - -#### `comonadStoreStoreT` - -``` purescript -instance comonadStoreStoreT :: (Comonad w) => ComonadStore s (StoreT s w) -``` - - -#### `experiment` - -``` purescript -experiment :: forall f a w s. (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a -``` - - -#### `peeks` - -``` purescript -peeks :: forall s a w. (ComonadStore s w) => (s -> s) -> w a -> a -``` - - -#### `seek` - -``` purescript -seek :: forall s a w. (ComonadStore s w, Extend w) => s -> w a -> w a -``` - - -#### `seeks` - -``` purescript -seeks :: forall s a w. (ComonadStore s w, Extend w) => (s -> s) -> w a -> w a -``` - - - -## Module Control.Comonad.Store.Trans - -#### `StoreT` - -``` purescript -newtype StoreT s w a - = StoreT (Tuple (w (s -> a)) s) -``` - - -#### `runStoreT` - -``` purescript -runStoreT :: forall s w a. StoreT s w a -> Tuple (w (s -> a)) s -``` - - -#### `functorStoreT` - -``` purescript -instance functorStoreT :: (Functor w) => Functor (StoreT s w) -``` - - -#### `extendStoreT` - -``` purescript -instance extendStoreT :: (Extend w) => Extend (StoreT s w) -``` - - -#### `comonadStoreT` - -``` purescript -instance comonadStoreT :: (Comonad w) => Comonad (StoreT s w) -``` - - -#### `comonadTransStoreT` - -``` purescript -instance comonadTransStoreT :: ComonadTrans (StoreT s) -``` - - - -## Module Control.Comonad.Traced - -#### `Traced` - -``` purescript -type Traced m = TracedT m Identity -``` - - -#### `runTraced` - -``` purescript -runTraced :: forall m a. Traced m a -> m -> a -``` - - -#### `traced` - -``` purescript -traced :: forall m a. (m -> a) -> Traced m a -``` - - - -## Module Control.Comonad.Traced.Class - -#### `ComonadTraced` - -``` purescript -class (Comonad w) <= ComonadTraced t w where - track :: forall a. t -> w a -> a -``` - - -#### `comonadTracedTracedT` - -``` purescript -instance comonadTracedTracedT :: (Comonad w, Monoid t) => ComonadTraced t (TracedT t w) -``` - - -#### `tracks` - -``` purescript -tracks :: forall w a t. (Comonad w, ComonadTraced t w) => (a -> t) -> w a -> a -``` - - -#### `listen` - -``` purescript -listen :: forall w a t. (Functor w) => TracedT t w a -> TracedT t w (Tuple a t) -``` - - -#### `listens` - -``` purescript -listens :: forall w a t b. (Functor w) => (t -> b) -> TracedT t w a -> TracedT t w (Tuple a b) -``` - - -#### `censor` - -``` purescript -censor :: forall w a t b. (Functor w) => (t -> t) -> TracedT t w a -> TracedT t w a -``` - - - -## Module Control.Comonad.Traced.Trans - -#### `TracedT` - -``` purescript -newtype TracedT t w a - = TracedT (w (t -> a)) -``` - - -#### `runTracedT` - -``` purescript -runTracedT :: forall w a t. TracedT t w a -> w (t -> a) -``` - - -#### `functorTracedT` - -``` purescript -instance functorTracedT :: (Functor w) => Functor (TracedT t w) -``` - - -#### `extendTracedT` - -``` purescript -instance extendTracedT :: (Extend w, Semigroup t) => Extend (TracedT t w) -``` - - -#### `comonadTracedT` - -``` purescript -instance comonadTracedT :: (Comonad w, Monoid t) => Comonad (TracedT t w) -``` - - -#### `comonadTransTracedT` - -``` purescript -instance comonadTransTracedT :: (Monoid t) => ComonadTrans (TracedT t) -``` - - - -## Module Control.Comonad.Trans - -#### `ComonadTrans` - -``` purescript -class ComonadTrans f where - lower :: forall w a. (Comonad w) => f w a -> w a -``` \ No newline at end of file diff --git a/docs/Comonad/Env.md b/docs/Comonad/Env.md new file mode 100644 index 00000000..b799e115 --- /dev/null +++ b/docs/Comonad/Env.md @@ -0,0 +1,169 @@ +# Module Documentation + +## Module Control.Comonad.Env.Class + + +This module defines the `ComonadEnv` type class and its instances. + +#### `ComonadEnv` + +``` purescript +class (Comonad w) <= ComonadEnv e w where + ask :: forall a. w a -> e + local :: forall a. (e -> e) -> w a -> w a +``` + +The `ComonadEnv` type class represents those monads which support a global environment via +`ask` and `local`. + +- `ask` reads the current environment from the context. +- `local` changes the value of the global environment. + +An implementation is provided for `EnvT`. + +Laws: + +- `ask (local f x) = f (ask x)` +- `extract (local _ x) = extract a` +- `extend g (local f x) = extend (g <<< local f) x` + +#### `asks` + +``` purescript +asks :: forall e1 e2 w a. (ComonadEnv e1 w) => (e1 -> e2) -> w e1 -> e2 +``` + +Get a value which depends on the environment. + +#### `comonadEnvTuple` + +``` purescript +instance comonadEnvTuple :: ComonadEnv e (Tuple e) +``` + + +#### `comonadEnvEnvT` + +``` purescript +instance comonadEnvEnvT :: (Comonad w) => ComonadEnv e (EnvT e w) +``` + + + +## Module Control.Comonad.Env.Trans + + +This module defines the environment comonad transformer, `EnvT`. + +#### `EnvT` + +``` purescript +newtype EnvT e w a + = EnvT (Tuple e (w a)) +``` + +The environment comonad transformer. + +This comonad transformer extends the context of a value in the base comonad with a _global environment_ of +type `e`. + +The `ComonadEnv` type class describes the operations supported by this comonad. + +#### `runEnvT` + +``` purescript +runEnvT :: forall e w a. EnvT e w a -> Tuple e (w a) +``` + +Unwrap a value in the `EnvT` comonad. + +#### `withEnvT` + +``` purescript +withEnvT :: forall e1 e2 w a. (e1 -> e2) -> EnvT e1 w a -> EnvT e2 w a +``` + +Change the environment type in an `EnvT` context. + +#### `mapEnvT` + +``` purescript +mapEnvT :: forall e w1 w2 a b. (w1 a -> w2 b) -> EnvT e w1 a -> EnvT e w2 b +``` + +Change the underlying comonad and data type in an `EnvT` context. + +#### `functorEnvT` + +``` purescript +instance functorEnvT :: (Functor w) => Functor (EnvT e w) +``` + + +#### `extendEnvT` + +``` purescript +instance extendEnvT :: (Extend w) => Extend (EnvT e w) +``` + + +#### `comonadEnvT` + +``` purescript +instance comonadEnvT :: (Comonad w) => Comonad (EnvT e w) +``` + + +#### `comonadTransEnvT` + +``` purescript +instance comonadTransEnvT :: ComonadTrans (EnvT e) +``` + + + +## Module Control.Comonad.Env + + +This module defines the `Env` comonad. + +#### `Env` + +``` purescript +type Env e = EnvT e Identity +``` + +The `Env` comonad is a synonym for the `EnvT` comonad transformer, applied +to the `Identity` monad. + +#### `runEnv` + +``` purescript +runEnv :: forall e a. Env e a -> Tuple e a +``` + +Unwrap a value in the `Env` comonad. + +#### `withEnv` + +``` purescript +withEnv :: forall e1 e2 a. (e1 -> e2) -> Env e1 a -> Env e2 a +``` + +Change the environment type in an `Env` computation. + +#### `mapEnv` + +``` purescript +mapEnv :: forall e a b. (a -> b) -> Env e a -> Env e b +``` + +Change the data type in an `Env` computation. + +#### `env` + +``` purescript +env :: forall e a. e -> a -> Env e a +``` + +Create a value in context in the `Env` comonad. \ No newline at end of file diff --git a/docs/Comonad/Store.md b/docs/Comonad/Store.md new file mode 100644 index 00000000..54acdd60 --- /dev/null +++ b/docs/Comonad/Store.md @@ -0,0 +1,160 @@ +# Module Documentation + +## Module Control.Comonad.Store.Class + + +This module defines the `ComonadStore` type class and its instances. + +#### `ComonadStore` + +``` purescript +class (Comonad w) <= ComonadStore s w where + pos :: forall a. w a -> s + peek :: forall a. s -> w a -> a +``` + +The `ComonadStore` type class represents those monads which support local position information via +`pos` and `peek`. + +- `pos` reads the current position. +- `peek` reads the value at the specified position in the specified context. + +An implementation is provided for `StoreT`. + +Laws: + +- `pos (extend _ x) = pos x` +- `peek (pos x) x = extract x` + +For example: + +```purescript +blur :: forall w. (ComonadStore Number w) -> w Number -> w Number +blur = extend \r -> (peeks (\n -> n - 1) r + peeks (\n -> n + 1) r) / 2) +``` + +#### `experiment` + +``` purescript +experiment :: forall f a w s. (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a +``` + +Extract a collection of values from positions which depend on the current position. + +#### `peeks` + +``` purescript +peeks :: forall s a w. (ComonadStore s w) => (s -> s) -> w a -> a +``` + +Extract a value from a position which depends on the current position. + +#### `seek` + +``` purescript +seek :: forall s a w. (ComonadStore s w, Extend w) => s -> w a -> w a +``` + +Reposition the focus at the specified position. + +#### `seeks` + +``` purescript +seeks :: forall s a w. (ComonadStore s w, Extend w) => (s -> s) -> w a -> w a +``` + +Reposition the focus at the specified position, which depends on the current position. + +#### `comonadStoreStoreT` + +``` purescript +instance comonadStoreStoreT :: (Comonad w) => ComonadStore s (StoreT s w) +``` + + + +## Module Control.Comonad.Store.Trans + + +This module defines the store comonad transformer, `StoreT`. + +#### `StoreT` + +``` purescript +newtype StoreT s w a + = StoreT (Tuple (w (s -> a)) s) +``` + +The store comonad transformer. + +This comonad transformer extends the context of a value in the base comonad so that the value +depends on a position of type `s`. + +The `ComonadStore` type class describes the operations supported by this comonad. + +#### `runStoreT` + +``` purescript +runStoreT :: forall s w a. StoreT s w a -> Tuple (w (s -> a)) s +``` + +Unwrap a value in the `StoreT` comonad. + +#### `functorStoreT` + +``` purescript +instance functorStoreT :: (Functor w) => Functor (StoreT s w) +``` + + +#### `extendStoreT` + +``` purescript +instance extendStoreT :: (Extend w) => Extend (StoreT s w) +``` + + +#### `comonadStoreT` + +``` purescript +instance comonadStoreT :: (Comonad w) => Comonad (StoreT s w) +``` + + +#### `comonadTransStoreT` + +``` purescript +instance comonadTransStoreT :: ComonadTrans (StoreT s) +``` + + + +## Module Control.Comonad.Store + + +This module defines the `Store` comonad. + +#### `Store` + +``` purescript +type Store s a = StoreT s Identity a +``` + +The `Store` comonad is a synonym for the `StoreT` comonad transformer, applied +to the `Identity` monad. + +#### `runStore` + +``` purescript +runStore :: forall s a. Store s a -> Tuple (s -> a) s +``` + +Unwrap a value in the `Store` comonad. + +#### `store` + +``` purescript +store :: forall s a. (s -> a) -> s -> Store s a +``` + +Create a value in context in the `Store` comonad. \ No newline at end of file diff --git a/docs/Comonad/Traced.md b/docs/Comonad/Traced.md new file mode 100644 index 00000000..126c7016 --- /dev/null +++ b/docs/Comonad/Traced.md @@ -0,0 +1,158 @@ +# Module Documentation + +## Module Control.Comonad.Traced.Class + + +This module defines the `ComonadTraced` type class and its instances. + +#### `ComonadTraced` + +``` purescript +class (Comonad w) <= ComonadTraced t w where + track :: forall a. t -> w a -> a +``` + +The `ComonadTraced` type class represents those monads which support relative (monoidal) +position information via `track`. + +- `track` extracts a value at the specified relative position. + +An implementation is provided for `TracedT`. + +Laws: + +- `track mempty = extract` +- `track s <<= track t x = track (s <> t) x` + +For example: + +```purescript +blur :: forall w. (ComonadTraced (Additive Number) w) -> w Number -> w Number +blur = extend \r -> (track (Additive (-1)) r + track (Additive 1) r) / 2 +``` + +#### `tracks` + +``` purescript +tracks :: forall w a t. (Comonad w, ComonadTraced t w) => (a -> t) -> w a -> a +``` + +Extracts a value at a relative position which depends on the current value. + +#### `listen` + +``` purescript +listen :: forall w a t. (Functor w) => TracedT t w a -> TracedT t w (Tuple a t) +``` + +Get the current position. + +#### `listens` + +``` purescript +listens :: forall w a t b. (Functor w) => (t -> b) -> TracedT t w a -> TracedT t w (Tuple a b) +``` + +Get a value which depends on the current position. + +#### `censor` + +``` purescript +censor :: forall w a t b. (Functor w) => (t -> t) -> TracedT t w a -> TracedT t w a +``` + +Apply a function to the current position. + +#### `comonadTracedTracedT` + +``` purescript +instance comonadTracedTracedT :: (Comonad w, Monoid t) => ComonadTraced t (TracedT t w) +``` + + + +## Module Control.Comonad.Traced.Trans + + +This module defines the cowriter comonad transformer, `TracedT`. + +#### `TracedT` + +``` purescript +newtype TracedT t w a + = TracedT (w (t -> a)) +``` + +The cowriter comonad transformer. + +This comonad transformer extends the context of a value in the base comonad so that the value +depends on a monoidal position of type `t`. + +The `ComonadTraced` type class describes the operations supported by this comonad. + +#### `runTracedT` + +``` purescript +runTracedT :: forall w a t. TracedT t w a -> w (t -> a) +``` + +Unwrap a value in the `TracedT` comonad. + +#### `functorTracedT` + +``` purescript +instance functorTracedT :: (Functor w) => Functor (TracedT t w) +``` + + +#### `extendTracedT` + +``` purescript +instance extendTracedT :: (Extend w, Semigroup t) => Extend (TracedT t w) +``` + + +#### `comonadTracedT` + +``` purescript +instance comonadTracedT :: (Comonad w, Monoid t) => Comonad (TracedT t w) +``` + + +#### `comonadTransTracedT` + +``` purescript +instance comonadTransTracedT :: (Monoid t) => ComonadTrans (TracedT t) +``` + + + +## Module Control.Comonad.Traced + + +This module defines the `Traced` comonad. + +#### `Traced` + +``` purescript +type Traced m = TracedT m Identity +``` + +The `Traced` comonad is a synonym for the `TracedT` comonad transformer, applied +to the `Identity` monad. + +#### `runTraced` + +``` purescript +runTraced :: forall m a. Traced m a -> m -> a +``` + +Unwrap a value in the `Traced` comonad. + +#### `traced` + +``` purescript +traced :: forall m a. (m -> a) -> Traced m a +``` + +Create a value in context in the `Traced` comonad. \ No newline at end of file diff --git a/docs/Comonad/Trans.md b/docs/Comonad/Trans.md new file mode 100644 index 00000000..c812b210 --- /dev/null +++ b/docs/Comonad/Trans.md @@ -0,0 +1,29 @@ +# Module Documentation + +## Module Control.Comonad.Trans + + +This module defines the `ComonadTrans` type class of _comonad transformers_. + +#### `ComonadTrans` + +``` purescript +class ComonadTrans f where + lower :: forall w a. (Comonad w) => f w a -> w a +``` + +The `ComonadTrans` type class represents _comonad transformers_. + +A comonad transformer is a type constructor of kind `(* -> *) -> * -> *`, which +takes a `Comonad` as its first argument, and returns another `Comonad`. + +This allows us to extend a comonad to provide additional context. By iterating this +process, we create comonad transformer _stacks_, which contain all of the contextual information +required for a particular computation. + +The laws state that `lower` is a `Comonad` morphism. + +Laws: + +- `extract (lower a) = extract a` +- `lower (extend w (f <<< lower)) = extend (lower w) f` \ No newline at end of file diff --git a/docs/Cont.md b/docs/Monad/Cont.md similarity index 100% rename from docs/Cont.md rename to docs/Monad/Cont.md diff --git a/docs/Error.md b/docs/Monad/Error.md similarity index 96% rename from docs/Error.md rename to docs/Monad/Error.md index 3ae944d9..6dfe52d7 100644 --- a/docs/Error.md +++ b/docs/Monad/Error.md @@ -30,10 +30,17 @@ Laws: - Pure: `catchError (pure a) f = pure a` -#### `monadErrorError` +#### `monadErrorEither` ``` purescript -instance monadErrorError :: MonadError e (Either e) +instance monadErrorEither :: MonadError e (Either e) +``` + + +#### `monadErrorMaybe` + +``` purescript +instance monadErrorMaybe :: MonadError Unit Maybe ``` diff --git a/docs/Maybe.md b/docs/Monad/Maybe.md similarity index 100% rename from docs/Maybe.md rename to docs/Monad/Maybe.md diff --git a/docs/RWS.md b/docs/Monad/RWS.md similarity index 100% rename from docs/RWS.md rename to docs/Monad/RWS.md diff --git a/docs/Reader.md b/docs/Monad/Reader.md similarity index 100% rename from docs/Reader.md rename to docs/Monad/Reader.md diff --git a/docs/State.md b/docs/Monad/State.md similarity index 100% rename from docs/State.md rename to docs/Monad/State.md diff --git a/docs/Trans.md b/docs/Monad/Trans.md similarity index 100% rename from docs/Trans.md rename to docs/Monad/Trans.md diff --git a/docs/Writer.md b/docs/Monad/Writer.md similarity index 100% rename from docs/Writer.md rename to docs/Monad/Writer.md diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index b62d3283..00000000 --- a/docs/README.md +++ /dev/null @@ -1,16 +0,0 @@ -## Module Documentation - -### Monad Transformers - -- [MonadTrans](Trans.md) -- [Errors](Error.md) -- [Maybe](Maybe.md) -- [State](State.md) -- [Writer](Writer.md) -- [Reader](Reader.md) -- [Reader/Writer/State](RWS.md) -- [CPS](Cont.md) - -### Comonad Transformers - -- [Comonad Transformers](Comonad.md) diff --git a/src/Control/Comonad/Env.purs b/src/Control/Comonad/Env.purs index d237af87..d197eb90 100644 --- a/src/Control/Comonad/Env.purs +++ b/src/Control/Comonad/Env.purs @@ -1,19 +1,27 @@ +-- | This module defines the `Env` comonad. + module Control.Comonad.Env where import Control.Comonad.Env.Trans import Data.Identity import Data.Tuple +-- | The `Env` comonad is a synonym for the `EnvT` comonad transformer, applied +-- | to the `Identity` monad. type Env e = EnvT e Identity +-- | Unwrap a value in the `Env` comonad. runEnv :: forall e a. Env e a -> Tuple e a runEnv x = runIdentity <$> runEnvT x +-- | Change the environment type in an `Env` computation. withEnv :: forall e1 e2 a. (e1 -> e2) -> Env e1 a -> Env e2 a withEnv = withEnvT +-- | Change the data type in an `Env` computation. mapEnv :: forall e a b. (a -> b) -> Env e a -> Env e b mapEnv = (<$>) +-- | Create a value in context in the `Env` comonad. env :: forall e a. e -> a -> Env e a env e a = EnvT $ Tuple e $ Identity a diff --git a/src/Control/Comonad/Env/Class.purs b/src/Control/Comonad/Env/Class.purs index e3d09f58..53339fdc 100644 --- a/src/Control/Comonad/Env/Class.purs +++ b/src/Control/Comonad/Env/Class.purs @@ -1,3 +1,5 @@ +-- | This module defines the `ComonadEnv` type class and its instances. + module Control.Comonad.Env.Class where import Control.Comonad @@ -6,9 +8,26 @@ import Control.Comonad.Env.Trans import Data.Tuple +-- | The `ComonadEnv` type class represents those monads which support a global environment via +-- | `ask` and `local`. +-- | +-- | - `ask` reads the current environment from the context. +-- | - `local` changes the value of the global environment. +-- | +-- | An implementation is provided for `EnvT`. +-- | +-- | Laws: +-- | +-- | - `ask (local f x) = f (ask x)` +-- | - `extract (local _ x) = extract a` +-- | - `extend g (local f x) = extend (g <<< local f) x` class (Comonad w) <= ComonadEnv e w where ask :: forall a. w a -> e local :: forall a. (e -> e) -> w a -> w a + +-- | Get a value which depends on the environment. +asks :: forall e1 e2 w a. (ComonadEnv e1 w) => (e1 -> e2) -> w e1 -> e2 +asks f x = f $ ask x instance comonadEnvTuple :: ComonadEnv e (Tuple e) where ask = fst @@ -18,6 +37,3 @@ instance comonadEnvEnvT :: (Comonad w) => ComonadEnv e (EnvT e w) where ask x = fst $ runEnvT x local f x = EnvT $ case runEnvT x of Tuple x y -> Tuple (f x) y - -asks :: forall e1 e2 w a. (ComonadEnv e1 w) => (e1 -> e2) -> w e1 -> e2 -asks f x = f $ ask x diff --git a/src/Control/Comonad/Env/Trans.purs b/src/Control/Comonad/Env/Trans.purs index f0c00723..decc813e 100644 --- a/src/Control/Comonad/Env/Trans.purs +++ b/src/Control/Comonad/Env/Trans.purs @@ -1,3 +1,5 @@ +-- | This module defines the environment comonad transformer, `EnvT`. + module Control.Comonad.Env.Trans where import Control.Comonad @@ -5,14 +7,23 @@ import Control.Comonad.Trans import Control.Extend import Data.Tuple +-- | The environment comonad transformer. +-- | +-- | This comonad transformer extends the context of a value in the base comonad with a _global environment_ of +-- | type `e`. +-- | +-- | The `ComonadEnv` type class describes the operations supported by this comonad. newtype EnvT e w a = EnvT (Tuple e (w a)) +-- | Unwrap a value in the `EnvT` comonad. runEnvT :: forall e w a. EnvT e w a -> Tuple e (w a) runEnvT (EnvT x) = x +-- | Change the environment type in an `EnvT` context. withEnvT :: forall e1 e2 w a. (e1 -> e2) -> EnvT e1 w a -> EnvT e2 w a withEnvT f (EnvT (Tuple e x)) = EnvT $ Tuple (f e) x +-- | Change the underlying comonad and data type in an `EnvT` context. mapEnvT :: forall e w1 w2 a b. (w1 a -> w2 b) -> EnvT e w1 a -> EnvT e w2 b mapEnvT f (EnvT (Tuple e x)) = EnvT $ Tuple e (f x) diff --git a/src/Control/Comonad/Store.purs b/src/Control/Comonad/Store.purs index 82e1e331..89a7bb13 100644 --- a/src/Control/Comonad/Store.purs +++ b/src/Control/Comonad/Store.purs @@ -1,13 +1,19 @@ +-- | This module defines the `Store` comonad. + module Control.Comonad.Store where import Control.Comonad.Store.Trans import Data.Identity import Data.Tuple +-- | The `Store` comonad is a synonym for the `StoreT` comonad transformer, applied +-- | to the `Identity` monad. type Store s a = StoreT s Identity a +-- | Unwrap a value in the `Store` comonad. runStore :: forall s a. Store s a -> Tuple (s -> a) s runStore s = swap (runIdentity <$> (swap $ runStoreT s)) +-- | Create a value in context in the `Store` comonad. store :: forall s a. (s -> a) -> s -> Store s a store f x = StoreT $ Tuple (Identity f) x diff --git a/src/Control/Comonad/Store/Class.purs b/src/Control/Comonad/Store/Class.purs index 8b62da14..9a9e6dc0 100644 --- a/src/Control/Comonad/Store/Class.purs +++ b/src/Control/Comonad/Store/Class.purs @@ -1,3 +1,5 @@ +-- | This module defines the `ComonadStore` type class and its instances. + module Control.Comonad.Store.Class where import Control.Comonad @@ -6,22 +8,45 @@ import Control.Extend import Data.Tuple +-- | The `ComonadStore` type class represents those monads which support local position information via +-- | `pos` and `peek`. +-- | +-- | - `pos` reads the current position. +-- | - `peek` reads the value at the specified position in the specified context. +-- | +-- | An implementation is provided for `StoreT`. +-- | +-- | Laws: +-- | +-- | - `pos (extend _ x) = pos x` +-- | - `peek (pos x) x = extract x` +-- | +-- | For example: +-- | +-- | ```purescript +-- | blur :: forall w. (ComonadStore Number w) -> w Number -> w Number +-- | blur = extend \r -> (peeks (\n -> n - 1) r + peeks (\n -> n + 1) r) / 2) +-- | ``` class (Comonad w) <= ComonadStore s w where pos :: forall a. w a -> s peek :: forall a. s -> w a -> a -instance comonadStoreStoreT :: (Comonad w) => ComonadStore s (StoreT s w) where - pos (StoreT (Tuple f s)) = s - peek s (StoreT (Tuple f _)) = extract f s - -experiment :: forall f a w s. (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a +-- | Extract a collection of values from positions which depend on the current position. +experiment :: forall f a w s. (ComonadStore s w, Functor f) => (s -> f s) -> w a -> f a experiment f x = flip peek x <$> f (pos x) +-- | Extract a value from a position which depends on the current position. peeks :: forall s a w. (ComonadStore s w) => (s -> s) -> w a -> a peeks f x = peek (f $ pos x) x +-- | Reposition the focus at the specified position. seek :: forall s a w. (ComonadStore s w, Extend w) => s -> w a -> w a seek s x = peek s $ duplicate x +-- | Reposition the focus at the specified position, which depends on the current position. seeks :: forall s a w. (ComonadStore s w, Extend w) => (s -> s) -> w a -> w a seeks f x = peeks f $ duplicate x + +instance comonadStoreStoreT :: (Comonad w) => ComonadStore s (StoreT s w) where + pos (StoreT (Tuple f s)) = s + peek s (StoreT (Tuple f _)) = extract f s \ No newline at end of file diff --git a/src/Control/Comonad/Store/Trans.purs b/src/Control/Comonad/Store/Trans.purs index 36491409..227aad4e 100644 --- a/src/Control/Comonad/Store/Trans.purs +++ b/src/Control/Comonad/Store/Trans.purs @@ -1,3 +1,5 @@ +-- | This module defines the store comonad transformer, `StoreT`. + module Control.Comonad.Store.Trans where import Control.Extend @@ -6,8 +8,15 @@ import Control.Comonad.Trans import Data.Tuple +-- | The store comonad transformer. +-- | +-- | This comonad transformer extends the context of a value in the base comonad so that the value +-- | depends on a position of type `s`. +-- | +-- | The `ComonadStore` type class describes the operations supported by this comonad. newtype StoreT s w a = StoreT (Tuple (w (s -> a)) s) +-- | Unwrap a value in the `StoreT` comonad. runStoreT :: forall s w a. StoreT s w a -> Tuple (w (s -> a)) s runStoreT (StoreT s) = s diff --git a/src/Control/Comonad/Traced.purs b/src/Control/Comonad/Traced.purs index 146728ae..25d18484 100644 --- a/src/Control/Comonad/Traced.purs +++ b/src/Control/Comonad/Traced.purs @@ -1,12 +1,18 @@ +-- | This module defines the `Traced` comonad. + module Control.Comonad.Traced where import Control.Comonad.Traced.Trans import Data.Identity +-- | The `Traced` comonad is a synonym for the `TracedT` comonad transformer, applied +-- | to the `Identity` monad. type Traced m = TracedT m Identity +-- | Unwrap a value in the `Traced` comonad. runTraced :: forall m a. Traced m a -> m -> a runTraced = runTracedT >>> runIdentity +-- | Create a value in context in the `Traced` comonad. traced :: forall m a. (m -> a) -> Traced m a traced = Identity >>> TracedT diff --git a/src/Control/Comonad/Traced/Class.purs b/src/Control/Comonad/Traced/Class.purs index e26d84e3..bd60fcc9 100644 --- a/src/Control/Comonad/Traced/Class.purs +++ b/src/Control/Comonad/Traced/Class.purs @@ -1,3 +1,5 @@ +-- | This module defines the `ComonadTraced` type class and its instances. + module Control.Comonad.Traced.Class where import Control.Comonad @@ -6,20 +8,42 @@ import Control.Comonad.Traced.Trans import Data.Monoid import Data.Tuple +-- | The `ComonadTraced` type class represents those monads which support relative (monoidal) +-- | position information via `track`. +-- | +-- | - `track` extracts a value at the specified relative position. +-- | +-- | An implementation is provided for `TracedT`. +-- | +-- | Laws: +-- | +-- | - `track mempty = extract` +-- | - `track s <<= track t x = track (s <> t) x` +-- | +-- | For example: +-- | +-- | ```purescript +-- | blur :: forall w. (ComonadTraced (Additive Number) w) -> w Number -> w Number +-- | blur = extend \r -> (track (Additive (-1)) r + track (Additive 1) r) / 2 +-- | ``` class (Comonad w) <= ComonadTraced t w where track :: forall a. t -> w a -> a -instance comonadTracedTracedT :: (Comonad w, Monoid t) => ComonadTraced t (TracedT t w) where - track t tr = extract (runTracedT tr) t - +-- | Extracts a value at a relative position which depends on the current value. tracks :: forall w a t. (Comonad w, ComonadTraced t w) => (a -> t) -> w a -> a tracks f w = track (f $ extract w) w - + +-- | Get the current position. listen :: forall w a t. (Functor w) => TracedT t w a -> TracedT t w (Tuple a t) listen tr = TracedT ((\f t -> Tuple (f t) t) <$> runTracedT tr) +-- | Get a value which depends on the current position. listens :: forall w a t b. (Functor w) => (t -> b) -> TracedT t w a -> TracedT t w (Tuple a b) listens f tr = TracedT ((\g t -> Tuple (g t) (f t)) <$> runTracedT tr) +-- | Apply a function to the current position. censor :: forall w a t b. (Functor w) => (t -> t) -> TracedT t w a -> TracedT t w a censor f tr = TracedT ((>>>) f <$> runTracedT tr) + +instance comonadTracedTracedT :: (Comonad w, Monoid t) => ComonadTraced t (TracedT t w) where + track t tr = extract (runTracedT tr) t \ No newline at end of file diff --git a/src/Control/Comonad/Traced/Trans.purs b/src/Control/Comonad/Traced/Trans.purs index 83320789..07757274 100644 --- a/src/Control/Comonad/Traced/Trans.purs +++ b/src/Control/Comonad/Traced/Trans.purs @@ -1,3 +1,5 @@ +-- | This module defines the cowriter comonad transformer, `TracedT`. + module Control.Comonad.Traced.Trans where import Control.Comonad @@ -7,8 +9,15 @@ import Control.Extend import Data.Monoid import Data.Tuple +-- | The cowriter comonad transformer. +-- | +-- | This comonad transformer extends the context of a value in the base comonad so that the value +-- | depends on a monoidal position of type `t`. +-- | +-- | The `ComonadTraced` type class describes the operations supported by this comonad. newtype TracedT t w a = TracedT (w (t -> a)) +-- | Unwrap a value in the `TracedT` comonad. runTracedT :: forall w a t. TracedT t w a -> w (t -> a) runTracedT (TracedT w) = w diff --git a/src/Control/Comonad/Trans.purs b/src/Control/Comonad/Trans.purs index 2e2b16f3..3f9982dd 100644 --- a/src/Control/Comonad/Trans.purs +++ b/src/Control/Comonad/Trans.purs @@ -1,6 +1,23 @@ +-- | This module defines the `ComonadTrans` type class of _comonad transformers_. + module Control.Comonad.Trans where import Control.Comonad +-- | The `ComonadTrans` type class represents _comonad transformers_. +-- | +-- | A comonad transformer is a type constructor of kind `(* -> *) -> * -> *`, which +-- | takes a `Comonad` as its first argument, and returns another `Comonad`. +-- | +-- | This allows us to extend a comonad to provide additional context. By iterating this +-- | process, we create comonad transformer _stacks_, which contain all of the contextual information +-- | required for a particular computation. +-- | +-- | The laws state that `lower` is a `Comonad` morphism. +-- | +-- | Laws: +-- | +-- | - `extract (lower a) = extract a` +-- | - `lower (extend w (f <<< lower)) = extend (lower w) f` class ComonadTrans f where lower :: forall w a. (Comonad w) => f w a -> w a