diff --git a/README.md b/README.md index 0b9cea8..c7940e7 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,14 @@ [![Build status](https://github.com/purescript/purescript-unlift/workflows/CI/badge.svg?branch=main)](https://github.com/purescript/purescript-unlift/actions?query=workflow%3ACI+branch%3Amain) [![Pursuit](https://pursuit.purescript.org/packages/purescript-unlift/badge)](https://pursuit.purescript.org/packages/purescript-unlift) -Standard library for working with monads at the base of a transformer stack. -`MonadBase` allow any base monad to be lifted into a transformed monad à la -`MonadEffect` and `MonadAff`. `MonadUnliftEffect`, `MonadUnliftAff`, and -`MonadUnlift` allow running a stateless transformed monad inside of a base -monad. Based on: +Classes that allow stateless monads to be "unlifted" into a base monad. + +- `MonadUnliftEffect`: Run any compatible monad in `Effect` +- `MonadUnliftAff`: Run any compatible monad in `Aff` +- `MonadUnlift`: Run any compatible monad in any base monad. + +Based on: -- [transformers-base](http://hackage.haskell.org/package/transformers-base) - [unliftio](http://hackage.haskell.org/package/unliftio) - [unlift](http://hackage.haskell.org/package/unlift) @@ -23,4 +24,3 @@ spago install unlift ## Documentation Module documentation is [published on Pursuit](http://pursuit.purescript.org/packages/purescript-unlift). - diff --git a/bower.json b/bower.json index d19744b..53da444 100644 --- a/bower.json +++ b/bower.json @@ -17,11 +17,14 @@ "purescript-aff": "^v6.0.0", "purescript-effect": "^v3.0.0", "purescript-either": "^v5.0.0", + "purescript-freet": "^v6.0.0", "purescript-identity": "^v5.0.0", "purescript-lists": "^v6.0.1", "purescript-maybe": "^v5.0.0", + "purescript-monad-control": "^v5.0.0", "purescript-prelude": "^v5.0.1", "purescript-st": "^v5.0.1", - "purescript-transformers": "^v5.2.0" + "purescript-transformers": "^v5.2.0", + "purescript-tuples": "^v6.0.1" } } diff --git a/spago.dhall b/spago.dhall index b5a8283..d893546 100644 --- a/spago.dhall +++ b/spago.dhall @@ -5,12 +5,15 @@ [ "aff" , "effect" , "either" + , "freet" , "identity" , "lists" , "maybe" + , "monad-control" , "prelude" , "st" , "transformers" + , "tuples" ] , packages = ./packages.dhall , sources = [ "src/**/*.purs" ] diff --git a/src/Control/Monad/Base.purs b/src/Control/Monad/Base.purs deleted file mode 100644 index 9f0c696..0000000 --- a/src/Control/Monad/Base.purs +++ /dev/null @@ -1,105 +0,0 @@ -module Control.Monad.Base where - -import Prelude - -import Control.Monad.Cont (ContT) -import Control.Monad.Except (ExceptT) -import Control.Monad.Identity.Trans (IdentityT) -import Control.Monad.List.Trans (ListT) -import Control.Monad.Maybe.Trans (MaybeT) -import Control.Monad.RWS (RWST) -import Control.Monad.Reader (ReaderT) -import Control.Monad.ST (ST) -import Control.Monad.State (StateT) -import Control.Monad.Trans.Class (class MonadTrans, lift) -import Control.Monad.Writer (WriterT) -import Data.Either (Either) -import Data.Identity (Identity) -import Data.List (List) -import Data.List.Lazy as LL -import Data.Maybe (Maybe) -import Effect (Effect) -import Effect.Aff (Aff) - --- | A class for lifting computations in a monad at the bottom of a transformer --- | stack. --- | --- | `MonadBase` is a generalization of the concept represented by classes like --- | `MonadEffect` and `MonadAff`. --- | --- | Instances should satisfy the following laws, which state that `liftBase` --- | is a transformer of monads: --- | --- | ```purescript --- | liftBase <<< pure = pure --- | liftBase (f =<< m) = liftBase <<< f =<< liftBase m --- | ``` -class (Monad b, Monad m) <= MonadBase b m | m -> b where - -- | Lift a computation from the base monad. - liftBase :: b ~> m - -instance MonadBase Array Array where - liftBase = identity - -instance MonadBase List List where - liftBase = identity - -instance MonadBase LL.List LL.List where - liftBase = identity - -instance MonadBase Maybe Maybe where - liftBase = identity - -instance MonadBase Effect Effect where - liftBase = identity - -instance MonadBase Aff Aff where - liftBase = identity - -instance MonadBase Identity Identity where - liftBase = identity - -instance MonadBase (Either e) (Either e) where - liftBase = identity - -instance MonadBase (ST s) (ST s) where - liftBase = identity - -instance MonadBase (Function r) (Function r) where - liftBase = identity - -instance MonadBase b m => MonadBase b (ListT m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (MaybeT m) where - liftBase = liftBaseDefault - -instance (Monoid w, MonadBase b m) => MonadBase b (WriterT w m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (ExceptT e m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (StateT s m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (ReaderT r m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (IdentityT m) where - liftBase = liftBaseDefault - -instance MonadBase b m => MonadBase b (ContT r m) where - liftBase = liftBaseDefault - -instance (Monoid w, MonadBase b m) => MonadBase b (RWST r w s m) where - liftBase = liftBaseDefault - --- | A default implementation of `liftBase` which is defined as --- | --- | ```purescript --- | lift <<< liftBase --- | ``` -liftBaseDefault - :: forall t m b. MonadTrans t => Monad m => MonadBase b m => b ~> t m -liftBaseDefault = lift <<< liftBase diff --git a/src/Control/Monad/Unlift.purs b/src/Control/Monad/Unlift.purs index 2c1f8d5..ddbd84c 100644 --- a/src/Control/Monad/Unlift.purs +++ b/src/Control/Monad/Unlift.purs @@ -3,14 +3,12 @@ module Control.Monad.Unlift where import Prelude import Control.Monad.Base (class MonadBase) -import Control.Monad.Identity.Trans (IdentityT(..)) import Control.Monad.Reader (ReaderT(..)) -import Control.Monad.ST (ST) import Data.Either (Either) import Data.Identity (Identity) import Data.List (List) -import Data.List.Lazy as LL import Data.Maybe (Maybe) +import Data.Tuple (Tuple) import Effect (Effect) import Effect.Aff (Aff) @@ -45,9 +43,6 @@ instance MonadUnlift Array Array where instance MonadUnlift List List where withRunInBase runAction = runAction identity -instance MonadUnlift LL.List LL.List where - withRunInBase runAction = runAction identity - instance MonadUnlift Maybe Maybe where withRunInBase runAction = runAction identity @@ -63,7 +58,7 @@ instance MonadUnlift Identity Identity where instance MonadUnlift (Either e) (Either e) where withRunInBase runAction = runAction identity -instance MonadUnlift (ST s) (ST s) where +instance Monoid a => MonadUnlift (Tuple a) (Tuple a) where withRunInBase runAction = runAction identity instance MonadUnlift b m => MonadUnlift b (ReaderT r m) where @@ -72,11 +67,12 @@ instance MonadUnlift b m => MonadUnlift b (ReaderT r m) where runAction \(ReaderT reader) -> runMInBase $ reader context -instance MonadUnlift b m => MonadUnlift b (IdentityT m) where - withRunInBase runAction = IdentityT $ - withRunInBase \runMInBase -> - runAction \(IdentityT a) -> - runMInBase a +-- TODO add MonadBase instance for IdentityT +-- instance MonadUnlift b m => MonadUnlift b (IdentityT m) where +-- withRunInBase runAction = IdentityT $ +-- withRunInBase \runMInBase -> +-- runAction \(IdentityT a) -> +-- runMInBase a -- | A newtype wrapper around a natural transformation from `m` to `b`. newtype Unlift :: forall k. (k -> Type) -> (k -> Type) -> Type