How to create a monad using StateT, ContT, and ReaderT?












2














How do I create a monad which uses State, Cont, and Reader transformers? I would like to read an environment, and update/use state. However, I would also like to pause/interrupt the action. For example, if a condition is met, the state remains unchanged.



So far I have a monad using ReaderT and StateT, but I cannot work out how to include ContT:



{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Cont

-- reader environment
type In = Integer

-- cont: if true then pause, else continue
type Pause = Bool

-- state environment:
newtype StateType = StateType { s :: Integer }

newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
deriving ( Functor, Applicative, Monad
, MonadReader In
, MonadCont Pause
, MonadState StateType
)

-- run monadic action
runM :: In -> Pause -> StateType -> M r -> StateType
runM inp pause initial act
= runIdentity -- unwrap identity
$ flip execStateT initial -- unwrap state
$ flip runContT pause -- unwrap cont
$ flip runReaderT inp -- unwrap reader
$ _unM act -- unwrap action


This gives the error:



* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|


Ok, but why does Pause need kind * -> *?... I'm drowning in types, in need of explanation. What form does Pause have to take, a function? How does ContT integrate? Ultimately, I plan to use Cont for a control structure.










share|improve this question
























  • A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
    – chi
    Nov 21 at 20:01










  • @chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
    – DavOS
    Nov 21 at 21:44
















2














How do I create a monad which uses State, Cont, and Reader transformers? I would like to read an environment, and update/use state. However, I would also like to pause/interrupt the action. For example, if a condition is met, the state remains unchanged.



So far I have a monad using ReaderT and StateT, but I cannot work out how to include ContT:



{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Cont

-- reader environment
type In = Integer

-- cont: if true then pause, else continue
type Pause = Bool

-- state environment:
newtype StateType = StateType { s :: Integer }

newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
deriving ( Functor, Applicative, Monad
, MonadReader In
, MonadCont Pause
, MonadState StateType
)

-- run monadic action
runM :: In -> Pause -> StateType -> M r -> StateType
runM inp pause initial act
= runIdentity -- unwrap identity
$ flip execStateT initial -- unwrap state
$ flip runContT pause -- unwrap cont
$ flip runReaderT inp -- unwrap reader
$ _unM act -- unwrap action


This gives the error:



* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|


Ok, but why does Pause need kind * -> *?... I'm drowning in types, in need of explanation. What form does Pause have to take, a function? How does ContT integrate? Ultimately, I plan to use Cont for a control structure.










share|improve this question
























  • A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
    – chi
    Nov 21 at 20:01










  • @chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
    – DavOS
    Nov 21 at 21:44














2












2








2


1





How do I create a monad which uses State, Cont, and Reader transformers? I would like to read an environment, and update/use state. However, I would also like to pause/interrupt the action. For example, if a condition is met, the state remains unchanged.



So far I have a monad using ReaderT and StateT, but I cannot work out how to include ContT:



{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Cont

-- reader environment
type In = Integer

-- cont: if true then pause, else continue
type Pause = Bool

-- state environment:
newtype StateType = StateType { s :: Integer }

newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
deriving ( Functor, Applicative, Monad
, MonadReader In
, MonadCont Pause
, MonadState StateType
)

-- run monadic action
runM :: In -> Pause -> StateType -> M r -> StateType
runM inp pause initial act
= runIdentity -- unwrap identity
$ flip execStateT initial -- unwrap state
$ flip runContT pause -- unwrap cont
$ flip runReaderT inp -- unwrap reader
$ _unM act -- unwrap action


This gives the error:



* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|


Ok, but why does Pause need kind * -> *?... I'm drowning in types, in need of explanation. What form does Pause have to take, a function? How does ContT integrate? Ultimately, I plan to use Cont for a control structure.










share|improve this question















How do I create a monad which uses State, Cont, and Reader transformers? I would like to read an environment, and update/use state. However, I would also like to pause/interrupt the action. For example, if a condition is met, the state remains unchanged.



So far I have a monad using ReaderT and StateT, but I cannot work out how to include ContT:



{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
-- monads
import Data.Functor.Identity (Identity, runIdentity)
import Control.Monad.State
import Control.Monad.Reader
import Control.Monad.Cont

-- reader environment
type In = Integer

-- cont: if true then pause, else continue
type Pause = Bool

-- state environment:
newtype StateType = StateType { s :: Integer }

newtype M r = M {_unM :: ReaderT In (ContT Pause (StateT StateType Identity)) r}
deriving ( Functor, Applicative, Monad
, MonadReader In
, MonadCont Pause
, MonadState StateType
)

-- run monadic action
runM :: In -> Pause -> StateType -> M r -> StateType
runM inp pause initial act
= runIdentity -- unwrap identity
$ flip execStateT initial -- unwrap state
$ flip runContT pause -- unwrap cont
$ flip runReaderT inp -- unwrap reader
$ _unM act -- unwrap action


This gives the error:



* Expected kind `* -> *', but `Pause' has kind `*'
* In the first argument of `MonadCont', namely `Pause'
In the newtype declaration for `M'
|
24| , MonadCont Pause
|


Ok, but why does Pause need kind * -> *?... I'm drowning in types, in need of explanation. What form does Pause have to take, a function? How does ContT integrate? Ultimately, I plan to use Cont for a control structure.







haskell monads monad-transformers continuations






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 11:09

























asked Nov 20 at 23:11









DavOS

6441621




6441621












  • A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
    – chi
    Nov 21 at 20:01










  • @chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
    – DavOS
    Nov 21 at 21:44


















  • A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
    – chi
    Nov 21 at 20:01










  • @chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
    – DavOS
    Nov 21 at 21:44
















A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
– chi
Nov 21 at 20:01




A few random comments: the order in which you "stack" the monad transformers sometimes (often) matters. I can't see if you got it right or not. Anyway, ContT Pause is ContT Bool and it looks a bit weird since it's (a -> m Bool) -> m Bool, which might or might not be what you want.
– chi
Nov 21 at 20:01












@chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
– DavOS
Nov 21 at 21:44




@chi In terms of stack ordering, I want to "read" an Integer, if the integer is odd then no state update occurs, if even then add it to the state (an accumulator). That is why I stacked them how they are, ReaderT (ContT (StateT))). May be incorrect, been reading docs to confirm. Concerning ContT Bool, I think this is the stem of my confusion. I originally looked at it like ReaderT or StateT which use In and StateType respectively. What is (a -> m Bool) -> m Bool? Seems more abstract than StateType or the Reader environment type. How does the ContT use the function in runM?
– DavOS
Nov 21 at 21:44












1 Answer
1






active

oldest

votes


















6














Unlike MonadReader and MonadState, the MonadCont type class takes only one parameter. Since that parameter m must be a Monad, it must have kind * -> *.



In your deriving clause, you want MonadCont, not MonadCont Pause.



added in response to followup question:



ContT is defined as:



newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }


Note that the r in your definition of newtype M r is passed as the final (a) parameter to ContT. Plugging in the variables, you have



ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}


This provides a computational context in which you can manipulate the StateType, and use delimited continuations. Eventually, you will construct a ContT Bool (State StateType) Bool. Then you can run the continuation (with evalContT), and return to the simpler State StateType context. (In practice, you may unwrap all 3 of your monad transformers in the same part of your program.)






share|improve this answer























  • Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
    – DavOS
    Nov 21 at 19:41








  • 1




    ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
    – bergey
    Dec 3 at 16:12











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403001%2fhow-to-create-a-monad-using-statet-contt-and-readert%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









6














Unlike MonadReader and MonadState, the MonadCont type class takes only one parameter. Since that parameter m must be a Monad, it must have kind * -> *.



In your deriving clause, you want MonadCont, not MonadCont Pause.



added in response to followup question:



ContT is defined as:



newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }


Note that the r in your definition of newtype M r is passed as the final (a) parameter to ContT. Plugging in the variables, you have



ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}


This provides a computational context in which you can manipulate the StateType, and use delimited continuations. Eventually, you will construct a ContT Bool (State StateType) Bool. Then you can run the continuation (with evalContT), and return to the simpler State StateType context. (In practice, you may unwrap all 3 of your monad transformers in the same part of your program.)






share|improve this answer























  • Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
    – DavOS
    Nov 21 at 19:41








  • 1




    ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
    – bergey
    Dec 3 at 16:12
















6














Unlike MonadReader and MonadState, the MonadCont type class takes only one parameter. Since that parameter m must be a Monad, it must have kind * -> *.



In your deriving clause, you want MonadCont, not MonadCont Pause.



added in response to followup question:



ContT is defined as:



newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }


Note that the r in your definition of newtype M r is passed as the final (a) parameter to ContT. Plugging in the variables, you have



ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}


This provides a computational context in which you can manipulate the StateType, and use delimited continuations. Eventually, you will construct a ContT Bool (State StateType) Bool. Then you can run the continuation (with evalContT), and return to the simpler State StateType context. (In practice, you may unwrap all 3 of your monad transformers in the same part of your program.)






share|improve this answer























  • Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
    – DavOS
    Nov 21 at 19:41








  • 1




    ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
    – bergey
    Dec 3 at 16:12














6












6








6






Unlike MonadReader and MonadState, the MonadCont type class takes only one parameter. Since that parameter m must be a Monad, it must have kind * -> *.



In your deriving clause, you want MonadCont, not MonadCont Pause.



added in response to followup question:



ContT is defined as:



newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }


Note that the r in your definition of newtype M r is passed as the final (a) parameter to ContT. Plugging in the variables, you have



ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}


This provides a computational context in which you can manipulate the StateType, and use delimited continuations. Eventually, you will construct a ContT Bool (State StateType) Bool. Then you can run the continuation (with evalContT), and return to the simpler State StateType context. (In practice, you may unwrap all 3 of your monad transformers in the same part of your program.)






share|improve this answer














Unlike MonadReader and MonadState, the MonadCont type class takes only one parameter. Since that parameter m must be a Monad, it must have kind * -> *.



In your deriving clause, you want MonadCont, not MonadCont Pause.



added in response to followup question:



ContT is defined as:



newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }


Note that the r in your definition of newtype M r is passed as the final (a) parameter to ContT. Plugging in the variables, you have



ContT Bool (State StateType) a = ContT { 
runContT :: (a -> State StateType Bool) -> (State StateType Bool)
}


This provides a computational context in which you can manipulate the StateType, and use delimited continuations. Eventually, you will construct a ContT Bool (State StateType) Bool. Then you can run the continuation (with evalContT), and return to the simpler State StateType context. (In practice, you may unwrap all 3 of your monad transformers in the same part of your program.)







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 26 at 17:23

























answered Nov 21 at 4:04









bergey

2,323516




2,323516












  • Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
    – DavOS
    Nov 21 at 19:41








  • 1




    ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
    – bergey
    Dec 3 at 16:12


















  • Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
    – DavOS
    Nov 21 at 19:41








  • 1




    ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
    – bergey
    Dec 3 at 16:12
















Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
– DavOS
Nov 21 at 19:41






Much thanks! Could you explain what the parameters to ContT mean? Namely in the line M r = {... Reader In (ContT (???) (StateT StateType Identity)) r }.
– DavOS
Nov 21 at 19:41






1




1




ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
– bergey
Dec 3 at 16:12




ContT is defined as newtype ContT r m a = ContT { runContT :: (a -> m r) -> m r }. m is the underlying Monad - (StateT StateType Identity)) in your example. a is the value at the current stage of computation. These m and a are the same for every Monad Transformer. r is the type at which ContT will eventually be run / eliminated, with evalContT
– bergey
Dec 3 at 16:12


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53403001%2fhow-to-create-a-monad-using-statet-contt-and-readert%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

404 Error Contact Form 7 ajax form submitting

How to know if a Active Directory user can login interactively

Refactoring coordinates for Minecraft Pi buildings written in Python