processStream :: Members '[Embed IO,
Output LogMessage,
NonDet,
Reader CommCentre,
State StreamingState,
LoginHandler,
Error String] r
=> Context
-- ^ Tcp connection context
-> Sem r ()
I need to call processStream from a callback below ((T.Context, S.SockAddr) -> m r), but unfortunately it has MonadMask constraint.
This is connect from Network.Simple.TCP.TLS package:
connect
:: (MonadIO m, E.MonadMask m)
=> T.ClientParams
-> S.HostName
-> S.ServiceName
-> ((T.Context, S.SockAddr) -> m r)
-> m r
Current problem:
connectAndAuthenticate :: Members '[Embed IO,
Output LogMessage,
NonDet,
Reader CommCentre,
State StreamingState,
LoginHandler,
Error String] r
=> String
-> Int
-> Sem r ()
connectAndAuthenticate hostName port = do
logDebug $ mconcat ["connectAndAuthenticate ["
, T.pack hostName
, ":"
, T.pack . show $ port
, "] - staring"
params <- liftIO $ newDefaultClientParams (hostName, B.empty)
-- The commented part below does not compile:
{-
• Could not deduce (Control.Monad.Catch.MonadMask (Sem r))
arising from a use of ‘connect’
from the context: Members
'[Embed IO, Output LogMessage, NonDet, Reader CommCentre,
State StreamingState, LoginHandler, Error String]
r
bound by the type signature for:
connectAndAuthenticate :: forall (r :: [(* -> *) -> * -> *]).
Members
'[Embed IO, Output LogMessage, NonDet,
Reader CommCentre, State StreamingState,
LoginHandler, Error String]
r =>
String -> Int -> Sem r ()
at src/BfHaskell/StreamingAPI/StreamingProcessor.hs:(236,1)-(245,34)
• In the expression: connect params hostName (show port)
In a stmt of a 'do' block:
connect params hostName (show port)
$ \ (ctx, _saddr) -> do processStream ctx
In the expression:
do logDebug
$ mconcat ["connectAndAuthenticate [", T.pack hostName, ....]
params <- liftIO $ newDefaultClientParams (hostName, B.empty)
connect params hostName (show port) $ \ (ctx, _saddr) -> do ...
logDebug "connectAndAuthenticate - finished"
|
260 | connect params hostName (show port) $ \(ctx, _saddr) -> do
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-}
{-
connect params hostName (show port) $ \(ctx, _saddr) -> do
processStream ctx
-}
logDebug "connectAndAuthenticate - finished"
@Martins@Love Waern (King of the Homeless) may have more insight on this problem, but I'm worried that in general, arbitrary Sem can't have valid MonadMask instance
Quick and dirty solution would be wrapping your Sem argument in a newtype that implements MonadMask through Member (Embed IO)
@TheMatten
Thank you for insight! I am afraid you might be right, because MonadMask has mask, which deals with async exception masking, and it might not be compatible with Polysemy design.
Do you think @Love Waern (King of the Homeless) shall read this forum or I should contact him in a different way?
Upsides:
- A Mask effect that covers exactly the power of MonadMask
- Support for a proper maskToFinal interpreter.
Downsides:
- Change to internals is non-trivial.
- maskToFinal has some wonky semantics in the interplay with effectful state from other effects.
My thoughts are that we implement 2. and add it to polysemy-zoo, but also look at implementing the change to the internals that enables 3., and then wait and see if we want to implement a Mask effect based upon it. I'll create issues about this in each respective repo.
A MonadMask constraint absorber with the following type signature: absorbMask :: Member (Final IO) r => (MonadMask (Sem r) => Sem r a) -> Sem r a Should be possible by lifting uninterrupti...
From the documentation for Weaving in Polysemy.Internal.Union: data Weaving e m a where Weaving :: Functor f => { weaveEffect :: e m a -- ^ The original effect GADT originally lifted via -- '...
I have the following function - processStream.
I need to call processStream from a callback below ((T.Context, S.SockAddr) -> m r), but unfortunately it has MonadMask constraint.
This is connect from Network.Simple.TCP.TLS package:
Current problem:
What are possible solutions?
I had a look at poysemy-zoo and it has Polysemy.ConstraintAbsorber, but I could not figure out if it is possible to wrap MonadMask using it?
@Martins @Love Waern (King of the Homeless) may have more insight on this problem, but I'm worried that in general, arbitrary
Sem
can't have validMonadMask
instanceQuick and dirty solution would be wrapping your
Sem
argument in anewtype
that implementsMonadMask
throughMember (Embed IO)
@TheMatten
Thank you for insight! I am afraid you might be right, because MonadMask has mask, which deals with async exception masking, and it might not be compatible with Polysemy design.
Do you think @Love Waern (King of the Homeless) shall read this forum or I should contact him in a different way?
I think he should get a notification anyway
Thanks!
I'm here. Funnily enough, what prevents
Sem
to haveMonadMask
is notmask
, but rather,generalBracket
.mask
is implementable through the following effect:@Love Waern (King of the Homeless) Thank you!
Let me take another look to see what can be done about
generalBracket
.Ok, so, to address this, it's possible for us to do one of three things:
Mask
be based upon theun
/block
primitives, rather than theMonadMask
primitives:Upsides:
- No type variable.
Downsides:
- Inflexible. Doesn't support
Final IO
rather than aMask
effect:Upsides:
- Doesn't require a
Mask
effectDownsides:
- Restricted to IO, rather than arbitrary
MonadMask
.Polysemy
to make interpretinggeneralBracket
possible. This enables the following:Upsides:
- A
Mask
effect that covers exactly the power ofMonadMask
- Support for a proper
maskToFinal
interpreter.Downsides:
- Change to internals is non-trivial.
-
maskToFinal
has some wonky semantics in the interplay with effectful state from other effects.My thoughts are that we implement 2. and add it to polysemy-zoo, but also look at implementing the change to the internals that enables 3., and then wait and see if we want to implement a
Mask
effect based upon it. I'll create issues about this in each respective repo.Wow! I am amazed! :)
Issues created:
https://github.com/polysemy-research/polysemy-zoo/issues/61
https://github.com/polysemy-research/polysemy/issues/304