From c09e465efb15adf8ca31ac5ca8a79f0a6582b849 Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 6 Aug 2019 11:40:15 -0400 Subject: [PATCH 1/2] :memo: RightModule and its laws. --- semantic-core/src/Control/Monad/Module.hs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/semantic-core/src/Control/Monad/Module.hs b/semantic-core/src/Control/Monad/Module.hs index 57483b349d..c58814064e 100644 --- a/semantic-core/src/Control/Monad/Module.hs +++ b/semantic-core/src/Control/Monad/Module.hs @@ -8,6 +8,23 @@ module Control.Monad.Module import Control.Effect.Carrier +-- | Modules over monads allow lifting of a monad’s product (i.e. 'Control.Monad.join') into another structure composed with the monad. A right-module @f m@ over a monad @m@ therefore allows one to extend @m@’s '>>=' operation to values of @f m@ using the '>>=*' operator. +-- +-- Note that we are calling this a right-module following Maciej Piróg, Nicolas Wu, & Jeremy Gibbons in _Modules Over Monads and their Algebras_; confusingly, other sources refer to this as a left-module. +-- +-- Laws: +-- +-- Right-identity: +-- +-- @ +-- m >>=* return = m +-- @ +-- +-- Associativity: +-- +-- @ +-- m >>=* (k >=> h) = (m >>=* k) >>=* h +-- @ class (forall g . Functor g => Functor (f g), HFunctor f) => RightModule f where (>>=*) :: Monad m => f m a -> (a -> m b) -> f m b infixl 1 >>=* From 93eba1d946ceb57c933161f4b0bfd0ac01299d0a Mon Sep 17 00:00:00 2001 From: Rob Rix Date: Tue, 6 Aug 2019 11:47:35 -0400 Subject: [PATCH 2/2] :memo: the practical takeaway. --- semantic-core/src/Control/Monad/Module.hs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/semantic-core/src/Control/Monad/Module.hs b/semantic-core/src/Control/Monad/Module.hs index c58814064e..84087d45d2 100644 --- a/semantic-core/src/Control/Monad/Module.hs +++ b/semantic-core/src/Control/Monad/Module.hs @@ -10,6 +10,8 @@ import Control.Effect.Carrier -- | Modules over monads allow lifting of a monad’s product (i.e. 'Control.Monad.join') into another structure composed with the monad. A right-module @f m@ over a monad @m@ therefore allows one to extend @m@’s '>>=' operation to values of @f m@ using the '>>=*' operator. -- +-- In practical terms, this means that we can describe syntax which cannot itself bind or be substituted for variables, but which can be substituted inside when containing a substitutable expression monad. For example, we might not want to allow variables in a declaration context, but might still want to be able to substitute for e.g. globally-bound variables inside declarations; a 'RightModule' instance expresses this relationship nicely. +-- -- Note that we are calling this a right-module following Maciej Piróg, Nicolas Wu, & Jeremy Gibbons in _Modules Over Monads and their Algebras_; confusingly, other sources refer to this as a left-module. -- -- Laws: