-
Notifications
You must be signed in to change notification settings - Fork 8
Implement initial BindLeft and MonadLeft #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
b9075b6
0acc6fc
610efd5
6baa15b
8bada1b
104768c
5f4da8a
a193890
3a0ed53
948d34e
99b4266
4793eec
32a32a1
92dd8ca
f80b235
4484988
1c5b583
5f23d85
5efcadf
3354b83
f188683
a3e9546
6bc197a
a64efb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module Control.ApplicativeLeft where | ||
|
||
import Prelude | ||
import Control.ApplyLeft (class ApplyLeft, lapply) | ||
|
||
-- | Same as `Applicative` but works on the left parameter in a Bifunctor. | ||
class ApplyLeft w <= ApplicativeLeft w where | ||
lpure :: forall a b. a -> w a b | ||
|
||
-- | Perform an applicative action when a condition is true. | ||
lwhen :: forall m c. ApplicativeLeft m => Boolean -> m Unit c -> m Unit c | ||
lwhen true m = m | ||
lwhen false _ = lpure unit | ||
|
||
-- | Perform an applicative action unless a condition is true. | ||
lunless :: forall m c. ApplicativeLeft m => Boolean -> m Unit c -> m Unit c | ||
lunless false m = m | ||
lunless true _ = lpure unit |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
module Control.ApplyLeft where | ||
|
||
import Prelude | ||
import Data.Bifunctor (class Bifunctor, lmap) | ||
|
||
-- | Same as `Apply` but works on the left parameter in a Bifunctor. | ||
class Bifunctor w <= ApplyLeft w where | ||
JordanMartinez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
lapply :: forall a b c. w (a -> b) c -> w a c -> w b c | ||
|
||
-- | Combine two effectful actions, keeping only the result of the first. | ||
lapplyFirst :: forall a b c w. ApplyLeft w => w a c -> w b c -> w a c | ||
lapplyFirst a b = lapply (lmap const a) b | ||
|
||
-- | Combine two effectful actions, keeping only the result of the second. | ||
lapplySecond :: forall w a b c. ApplyLeft w => w a c -> w b c -> w b c | ||
lapplySecond a b = lapply (lmap (const identity) a) b | ||
|
||
-- | Lift a function of two arguments to a function which accepts and returns | ||
-- | values wrapped with the type constructor `f`. | ||
llift2 :: forall a b c w x. ApplyLeft w => (a -> b -> c) -> w a x -> w b x -> w c x | ||
llift2 f a b = f `lmap` a `lapply` b | ||
|
||
-- | Lift a function of three arguments to a function which accepts and returns | ||
-- | values wrapped with the type constructor `f`. | ||
llift3 :: forall a b c d w x. ApplyLeft w => (a -> b -> c -> d) -> w a x -> w b x -> w c x -> w d x | ||
llift3 f a b c = f `lmap` a `lapply` b `lapply` c | ||
|
||
-- | Lift a function of four arguments to a function which accepts and returns | ||
-- | values wrapped with the type constructor `f`. | ||
llift4 :: forall a b c d e w x. ApplyLeft w => (a -> b -> c -> d -> e) -> w a x -> w b x -> w c x -> w d x -> w e x | ||
llift4 f a b c d = f `lmap` a `lapply` b `lapply` c `lapply` d | ||
|
||
-- | Lift a function of five arguments to a function which accepts and returns | ||
-- | values wrapped with the type constructor `f`. | ||
llift5 :: forall a b c d e g w x. ApplyLeft w => (a -> b -> c -> d -> e -> g) -> w a x -> w b x -> w c x -> w d x -> w e x -> w g x | ||
llift5 f a b c d e = f `lmap` a `lapply` b `lapply` c `lapply` d `lapply` e |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
module Control.BindLeft where | ||
|
||
import Data.Unit (Unit) | ||
import Control.Category (identity) | ||
|
||
-- | Same as `Discard` but works on the left parameter of the bifunctor | ||
-- | rather than the right parameter, which is the default for `Discard`. | ||
class DiscardLeft a where | ||
ldiscard :: forall k (m :: Type -> k -> Type) b r. BindLeft m => m a r -> (a -> m b r) -> m b r | ||
|
||
instance discardLeftUnit :: DiscardLeft Unit where | ||
ldiscard ma aToMB = lbind ma aToMB | ||
JordanMartinez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
-- | Same as `Bind` but works on the left parameter of the bifunctor | ||
-- | rather than the right parameter, which is the default for `Bind`. | ||
class BindLeft :: forall k. (Type -> k -> Type) -> Constraint | ||
class BindLeft m where | ||
lbind :: forall a b r. m a r -> (a -> m b r) -> m b r | ||
|
||
ljoin :: forall m a r. BindLeft m => m (m a r) r -> m a r | ||
ljoin m = lbind m identity | ||
|
||
lcomposeKleisli :: forall m a b c r. BindLeft m => (a -> m b r) -> (b -> m c r) -> a -> m c r | ||
lcomposeKleisli aToMB bToMC a = lbind (aToMB a) bToMC | ||
|
||
lcomposeKleisliFlipped :: forall m a b c r. BindLeft m => (b -> m c r) -> (a -> m b r) -> a -> m c r | ||
lcomposeKleisliFlipped bToMC aToMB a = lbind (aToMB a) bToMC | ||
JordanMartinez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
lifM :: forall m a r. BindLeft m => m Boolean r -> m a r -> m a r -> m a r | ||
lifM cond truePath falsePath = lbind cond \b -> if b then truePath else falsePath | ||
JordanMartinez marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Control.MonadLeft where | ||
|
||
import Control.ApplicativeLeft (class ApplicativeLeft, lwhen, lunless) | ||
import Control.BindLeft (class BindLeft, lbind) | ||
import Data.Unit (Unit) | ||
|
||
class (ApplicativeLeft m, BindLeft m) <= MonadLeft m | ||
|
||
-- | Perform a monadic action when a condition is true, where the conditional | ||
-- | value is also in a monadic context. | ||
lwhenM :: forall m c. MonadLeft m => m Boolean c -> m Unit c -> m Unit c | ||
lwhenM mb m = lbind mb \b -> lwhen b m | ||
|
||
-- | Perform a monadic action unless a condition is true, where the conditional | ||
-- | value is also in a monadic context. | ||
lunlessM :: forall m c. MonadLeft m => m Boolean c -> m Unit c -> m Unit c | ||
lunlessM mb m = lbind mb \b -> lunless b m |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
-- | Enables one to use `ado notation` and `do notation` on the left parameter | ||
-- | of a Bifunctor. | ||
-- | | ||
-- | `ado notation` example | ||
-- | ``` | ||
-- | import Control.MonadLeft.Qualified as MonadLeft | ||
-- | | ||
-- | foo :: Either Int String -> Either String String | ||
-- | foo comp = MonadLeft.ado | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the convention be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I read |
||
-- | a <- comp | ||
-- | b <- comp | ||
-- | in show $ a + b | ||
-- | ``` | ||
-- | `do notation` example | ||
-- | ``` | ||
-- | import Control.MonadLeft.Qualified as MonadLeft | ||
-- | | ||
-- | foo :: Either Int String -> Either String String | ||
-- | foo comp = MonadLeft.do | ||
-- | a <- comp | ||
-- | b <- comp | ||
-- | lpure $ show $ a + b | ||
-- | ``` | ||
module Control.MonadLeft.Qualified where | ||
JordanMartinez marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import Control.ApplyLeft (class ApplyLeft, lapply) | ||
import Control.BindLeft (class BindLeft, lbind, class DiscardLeft, ldiscard) | ||
import Data.Bifunctor (class Bifunctor, lmap) | ||
|
||
discard :: forall m a b r. DiscardLeft a => BindLeft m => m a r -> (a -> m b r) -> m b r | ||
discard = ldiscard | ||
|
||
bind :: forall m a b r. BindLeft m => m a r -> (a -> m b r) -> m b r | ||
bind = lbind | ||
|
||
apply :: forall m a b c. ApplyLeft m => m (a -> b) c -> m a c -> m b c | ||
apply = lapply | ||
|
||
map :: forall m a b c. Bifunctor m => (a -> b) -> m a c -> m b c | ||
map = lmap |
Uh oh!
There was an error while loading. Please reload this page.