-
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
add MonadThrow and MonadCatch instances for Stream #121
base: master
Are you sure you want to change the base?
Conversation
These are equivalent to the code in the existing MonadError instance.
Please leave a comment proving the |
Is the following correct/complete? I can prove the Lemma 1: throwM e >>= f = throwM e Proof: throwM e >>= f =
-- MonadThrow law (in reverse) for some arbitrary action 'w'
-- (in particular, you can always choose w = throwM e)
(throwM e >> w) >>= f =
-- my assumption
(throwM e >>= \_ -> w) >>= f =
-- Monad associativity
throwM e >>= (\x -> (\_ -> w) x >>= f) =
-- beta reduction
throwM e >>= (\_ -> w >>= f) =
-- my assumption, again
throwM e >> (w >>= f)
-- MonadThrow law
throwM e Lemma 2: fmap f (throwM e) = throwM e Proof: fmap f (throwM e) =
-- behavior of fmap for monads
throwM e >>= return . f
-- lemma 1
throwM e Theorem 1 (MonadThrow law for throwM e >> f = throwM e Proof: throwM e >> f =
-- definition of throwM, (>>) for Stream
lift (throwM e) *> f =
-- definition of lift for Stream
Effect (fmap Return (throwM e)) *> f =
-- lemma 2 for m
Effect (throwM e) *> f =
-- definition of (*>) for Stream
Effect (fmap loop (throwM e)) = -- this 'loop' is a local function in (*>) and hides a reference to 'f'
-- lemma 2 for m
Effect (throwM e) =
-- lemma 2 for m
Effect (fmap Return (throwM e)) =
-- definition of lift for Stream
lift (throwM e) =
-- definition of throwM for Stream
throwM e Theorem 2 (MonadCatch law for catch (throwM e) f = f e Proof: catch (throwM e) f =
-- definition of throwM for Stream
catch (lift (throwM e)) f =
-- definition of lift for Stream
catch (Effect (fmap Return (throwM e))) f =
-- lemma 2 for m
catch (Effect (throwM e)) f =
-- definition of catch for Stream
Effect (fmap loop (throwM e) `catch` (return . f)) =
-- lemma 2 for m
Effect (throwM e `catch` (return . f)) =
-- MonadCatch law for m
Effect (return (f e))
-- definition of effect
effect (return (f e))
-- specification/law of effect
(join . lift) (return (f e))
-- associativity of (.)
join ((lift . return) (f e))
-- MonadTrans law
join (return (f e))
-- definition of join
return (f e) >>= id
-- Monad law
id (f e)
-- definition of id
f e |
As for examples of desirable behavior, do you mean something like this? S.print (do
S.yield "start"
do { xs <- liftIO $ fmap lines (readFile "some-imaginary-file");
S.each xs }
S.yield "finish"
)
{-
"start"
*** Exception: some-imaginary-file: openFile: does not exist (No such file or directory)
-} S.print (do
S.yield "start"
do { xs <- liftIO $ fmap lines (readFile "some-imaginary-file");
S.each xs }
`catchIOError` (\e -> do
liftIO $ hPutStrLn stderr $ "caught an error: " ++ show e
S.yield "something else"
)
S.yield "finish"
)
{-
"start"
caught an error: some-imaginary-file: openFile: does not exist (No such file or directory)
"something else"
"finish"
-} What would "bad" behavior look like? |
@treeowl Ping? |
Been sick for a week. Please ping again later. |
Get well soon! |
Ping? |
@treeowl ping |
No description provided.