Zulip Chat Archive
Stream: mathlib4
Topic: MonadExcept in the ContT monad
Eric Wieser (Jul 14 2023 at 17:37):
@Kyle Miller spotted that something is wrong with the tryCatch
in the ContT
(continuation) monad:
def foo : ContT Bool (Except String) Bool := do
let x ← try pure true catch _ => return false
throw s!"oh no {x}"
#eval foo.run pure
-- `Except.ok false`, no error; should be `Except.error "oh no true"`
the github discussion has some ideas for how to fix this, but none of them fully work.
Eric Wieser (Jul 14 2023 at 17:40):
Kyle suggested
Maybe this is it? Notice that
ε
has to be in the same universe asr
, and everything has to be constrained toContT r m r
.def ContT.tryCatch (ε : Type u) [Monad m] [MonadExceptOf ε m] (act : ContT r m r) (h : ε → ContT r m r) : ContT r m r := fun c => do match ← try Sum.inr <$> act pure catch e => pure (Sum.inl e) with | Sum.inr v => c v | Sum.inl e => h e c
which looks correct, but doesn't work for a MonadExcept
instance
Kyle Miller (Jul 14 2023 at 17:46):
ContT
also seems like it just might not be suitable for a try
/catch
, at least if you expect a finally
clause that always runs, since ContT
lets you do an early return from anywhere. This ContT r m r
type seems to be what you need to delimit a continuation. (Here's some Haskell)
Eric Wieser (Jul 14 2023 at 17:49):
Ah, I hadn't quite made the connection that try
/catch
enables finally
Eric Wieser (Jul 14 2023 at 17:49):
And https://www.yesodweb.com/blog/2014/05/exceptions-cont-monads suggests that finally
can't exist in ContT
James Gallicchio (Jul 14 2023 at 18:29):
It is odd that we don't separate catch and mask into two classes. This isn't the first time I've found it awkward.
Last updated: Dec 20 2023 at 11:08 UTC