How to create a monad using StateT, ContT, and ReaderT?
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
add a comment |
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
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
isContT 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. ConcerningContT Bool
, I think this is the stem of my confusion. I originally looked at it likeReaderT
orStateT
which useIn
andStateType
respectively. What is(a -> m Bool) -> m Bool
? Seems more abstract thanStateType
or the Reader environment type. How does theContT
use the function inrunM
?
– DavOS
Nov 21 at 21:44
add a comment |
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
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
haskell monads monad-transformers continuations
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
isContT 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. ConcerningContT Bool
, I think this is the stem of my confusion. I originally looked at it likeReaderT
orStateT
which useIn
andStateType
respectively. What is(a -> m Bool) -> m Bool
? Seems more abstract thanStateType
or the Reader environment type. How does theContT
use the function inrunM
?
– DavOS
Nov 21 at 21:44
add a comment |
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
isContT 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. ConcerningContT Bool
, I think this is the stem of my confusion. I originally looked at it likeReaderT
orStateT
which useIn
andStateType
respectively. What is(a -> m Bool) -> m Bool
? Seems more abstract thanStateType
or the Reader environment type. How does theContT
use the function inrunM
?
– 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
add a comment |
1 Answer
1
active
oldest
votes
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.)
Much thanks! Could you explain what the parameters toContT
mean? Namely in the lineM r = {... Reader In (ContT (???) (StateT StateType Identity)) r }
.
– DavOS
Nov 21 at 19:41
1
ContT is defined asnewtype 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. Thesem
anda
are the same for every Monad Transformer.r
is the type at whichContT
will eventually be run / eliminated, withevalContT
– bergey
Dec 3 at 16:12
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.)
Much thanks! Could you explain what the parameters toContT
mean? Namely in the lineM r = {... Reader In (ContT (???) (StateT StateType Identity)) r }
.
– DavOS
Nov 21 at 19:41
1
ContT is defined asnewtype 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. Thesem
anda
are the same for every Monad Transformer.r
is the type at whichContT
will eventually be run / eliminated, withevalContT
– bergey
Dec 3 at 16:12
add a comment |
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.)
Much thanks! Could you explain what the parameters toContT
mean? Namely in the lineM r = {... Reader In (ContT (???) (StateT StateType Identity)) r }
.
– DavOS
Nov 21 at 19:41
1
ContT is defined asnewtype 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. Thesem
anda
are the same for every Monad Transformer.r
is the type at whichContT
will eventually be run / eliminated, withevalContT
– bergey
Dec 3 at 16:12
add a comment |
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.)
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.)
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 toContT
mean? Namely in the lineM r = {... Reader In (ContT (???) (StateT StateType Identity)) r }
.
– DavOS
Nov 21 at 19:41
1
ContT is defined asnewtype 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. Thesem
anda
are the same for every Monad Transformer.r
is the type at whichContT
will eventually be run / eliminated, withevalContT
– bergey
Dec 3 at 16:12
add a comment |
Much thanks! Could you explain what the parameters toContT
mean? Namely in the lineM r = {... Reader In (ContT (???) (StateT StateType Identity)) r }
.
– DavOS
Nov 21 at 19:41
1
ContT is defined asnewtype 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. Thesem
anda
are the same for every Monad Transformer.r
is the type at whichContT
will eventually be run / eliminated, withevalContT
– 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
isContT 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. ConcerningContT Bool
, I think this is the stem of my confusion. I originally looked at it likeReaderT
orStateT
which useIn
andStateType
respectively. What is(a -> m Bool) -> m Bool
? Seems more abstract thanStateType
or the Reader environment type. How does theContT
use the function inrunM
?– DavOS
Nov 21 at 21:44