Finally catching? - Polysemy

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Sandy Maguire

Hi friends, I'm playing with polysemy again! Trying to figure out whether I can implement MonadCatch via Final IO?

Sandy Maguire

i have to admit i don't really "get" final

Sandy Maguire

is love still involved?

Torsten Schmits

yes, he's been working on a core rewrite for version 2, but he's been very busy lately with thesis and now the new job

Sandy Maguire
instance Member (Final IO) r => Catch.MonadCatch (Sem r) where
  catch m handler = withStrategicToFinal @IO $ do
    m' <- runS m
    st <- getInitialStateS
    handler' <- bindS handler
    pure $ m' `Catch.catch` \e -> handler' $ e <$ st
Sandy Maguire

this looks right to me

Torsten Schmits

alternatively with withWeavingToFinal:

instance Member (Final IO) r => Catch.MonadCatch (Sem r) where
  catch m handler =
    withWeavingToFinal \ s wv _ ->
      wv (m <$ s) `Catch.catch` \ e ->
        wv (handler e <$ s)
Torsten Schmits

both discard State though

Love Waern (King of the Homeless)

Both of your definitions are correct. Discarding state in the handler is necessary and expected.

Sandy Maguire

can we implement mask?

Sandy Maguire
mask :: Member (Final IO) r
     => ((forall a. Sem r a -> Sem r a) -> Sem r b)
     -> Sem r b
mask f = withWeavingToFinal $ \st lower ins ->
  lower $ f (\z -> fmap (fromJust . ins) $ embedFinal @IO $ X.mask $ \y -> y $ lower $ z <$ st) <$ st
Sandy Maguire

whichi is OBVIOUSLY WRONG

Torsten Schmits
mask ::
  forall r a .
  Member (Final IO) r =>
  ((forall x . Sem r x -> Sem r x) -> Sem r a) ->
  Sem r a
mask f =
  withStrategicToFinal @IO $
    controlS' \ lowerStrat ->
      X.mask \ restore ->
        lowerStrat do
          let
            res :: forall x . Sem r x -> Sem r x
            res mx =
              controlF \ lower -> restore (lower mx)
          controlS \ lowerOuter -> lowerOuter (f res)

not sure this is sound :speechless:

Torsten Schmits

FYI Love gave an implementation for v1 here: https://github.com/polysemy-research/polysemy/issues/135#issuecomment-530367719

this uses the same approach as I did – running a separate, nested Final action for the restore arg