-
Notifications
You must be signed in to change notification settings - Fork 30
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
bearriver: RandT and other transformers don't work directly #65
Comments
I had the same problem but instead of the RandT I am using StateT (they are isomorph as RandT is implemented using a StateT). I was able to solve it with the approach mentioned by @turion above. Here is my code, I hope it provides some help: type Agent m o d e = SF (StateT (AgentOut m o d e) m) (AgentIn o d e, e) e
data AgentIn o d e = ...
data AgentOut m o d e = ...
runAgent :: Monad m
=> SF m
(Agent m o d e, AgentIn o d e, e)
(AgentOut m o d e, (e, Agent m o d e))
runAgent = runStateSF_ runAgentAux agentOut
where
runAgentAux :: Monad m
=> SF (StateT (AgentOut m o d e) m)
(Agent m o d e, AgentIn o d e, e)
(e, Agent m o d e)
runAgentAux = arrM (\(sf, ain, e) -> unMSF sf (ain, e))
runStateSF_ :: Monad m => SF (StateT s m) a b -> s -> SF m a (s, b)
runStateSF_ sf = runStateS_ $ liftMSFPurer commute sf
commute :: Monad m => ReaderT r (StateT s m) a -> StateT s (ReaderT r m) a
commute (ReaderT read) =
StateT (\s ->
(ReaderT (\r -> let (StateT st) = read r
in st s))) |
Wow. I just figured out that import Control.Monad.Morph
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
commuteReaderTF :: (MonadTrans t, MFunctor t, Monad m) => t (ReaderT r m) a -> ReaderT r (t m) a
commuteReaderTF trma = ReaderT $ \r -> hoist (flip runReaderT r) trma |
Note that it's in general impossible to commute dontpushme :: Monad m => ReaderT Bool (ExceptT () m) ()
dontpushme = ReaderT $ \b -> if b then throwE () else return () Depending on the environment variable So we'd still be left with implementing those commutations for every single transformer that we want to handle in bearriver. |
Sorry, my previous comment is incorrect. I should have said that |
I am currently experimenting with STM: what I want to do is to run a SF which has a type Agent m o d = SF (RandT g STM) (AgentIn d) (AgentOut o d)
runAgents :: RandomGen g
=> SF (RandT g IO)
([Agent (RandT g STM) o d], [AgentIn d])
([Agent (RandT g STM) o d], [AgentOut o d])
runAgents = readerS $ proc (dt, (sfs, ins)) -> do
let asIns = zipWith (\sf ain -> (dt, (ain, sf))) sfs ins
arets <- mapMSF (runReaderS runAgentParallelSF) -< asIns
let (aos, sfs') = unzip arets
returnA -< (sfs', aos)
runAgentParallelSF :: RandomGen g
=> SF (RandT g IO)
(AgentIn d, Agent (RandT g STM) o d)
(AgentOut o d, Agent (RandT g STM) o d)
runAgentParallelSF = ?
runAgentParallel :: AgentIn d
-> Agent (RandT g STM) o d
-> IO (AgentOut o d, Agent (RandT g STM) o d)
runAgentParallel aid sf = do
-- how to extract the STM from sf?
-- let stmAction = ...
a <- async $ atomically stmAction
(ao, sf') <- wait a
return (ao, sf') |
Yep, should work. Can you open a separate issue, explain your desired result and write down the type signatures of the functions you want to use?
|
This has been stuck for a while. Closing due to lack of activity. |
Disclaimer: I haven't tested this yet.
It seems to me that
RandT
is not usable yet the way we'd like it to use.Typical dunai use case
Problem in bearriver
This doesn't work in bearriver since an
SF m a b
is anMSF (ReaderT DTime m) a b
, which means that the outermost monad is always aReaderT
. To remove theRandT
layer, it must first be commuted past theReaderT
layer, i.e. one must define:Then one needs to hoist an
SF (RandT g m) a b
along this monad morphism and then applyevalRandS
, i.e.:Not sure whether the names are ok like this or should be improved.
Other monads
This is actually an issue for other transformers as well. We should maybe think about a more general solution, i.e. we've already axiomatised elsewhere what it means to be able to commute past a
ReaderT
layer.The text was updated successfully, but these errors were encountered: