Advertisement
Guest User

Untitled

a guest
Jun 26th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.44 KB | None | 0 0
  1. -- see Control.Monad.Except
  2. action :: (MonadExcept String m, MonadWriter String m) =>
  3. m ()
  4. action = do tell "a"
  5. tell "b"
  6. throwError "c"
  7. tell "d"
  8.  
  9. -- run action and massage it into your format
  10. yourOutput :: (Maybe String, String)
  11. yourOutput = runWriter $ fmap (either Just (const Nothing)) $ runExceptT actions
  12.  
  13. action :: MonadWriter String m => m ()
  14. action = do tell "a"
  15. tell "b"
  16. error "c"
  17. tell "d"
  18.  
  19. runWriter action =
  20. ( ()
  21. , "a" ++ "b" ++ (case error "c" of (_, c) -> c) ++ "d"
  22. )
  23.  
  24. -- can also be seen as Free (a,) () -> Free (a,) (Maybe e)
  25. -- essentially, that type encodes the intuition that a list may end in [] (nil)
  26. -- or in an error
  27. salvageList :: Exception e => [a] -> IO ([a], Maybe e)
  28. salvageList xs = catch (do xs' <- evaluate xs
  29. case xs' of
  30. [] -> return ([], Nothing)
  31. (x : tl) -> do (tl', e) <- salvageList tl
  32. return (x : tl', e)
  33. ) (e -> return ([], Just e))
  34.  
  35. -- we get the return value, too! that makes me feel... surprisingly weirded out!
  36. yourOutputPlus :: IO ((), Maybe String, String)
  37. yourOutputPlus = do let (val, log) = runWriter action
  38. (realLog, error) <- salvageList log
  39. return (val, fmap ((ErrorCall msg) -> msg) error, realLog)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement