{"action":"created","issue":{"url":"https://api.github.com/repos/ekmett/machines/issues/59","labels_url":"https://api.github.com/repos/ekmett/machines/issues/59/labels{/name}","comments_url":"https://api.github.com/repos/ekmett/machines/issues/59/comments","events_url":"https://api.github.com/repos/ekmett/machines/issues/59/events","html_url":"https://github.com/ekmett/machines/issues/59","id":102650844,"number":59,"title":"Make it easy to write stateful machines","user":{"login":"treeowl","id":1893117,"avatar_url":"https://avatars.githubusercontent.com/u/1893117?v=3","gravatar_id":"","url":"https://api.github.com/users/treeowl","html_url":"https://github.com/treeowl","followers_url":"https://api.github.com/users/treeowl/followers","following_url":"https://api.github.com/users/treeowl/following{/other_user}","gists_url":"https://api.github.com/users/treeowl/gists{/gist_id}","starred_url":"https://api.github.com/users/treeowl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/treeowl/subscriptions","organizations_url":"https://api.github.com/users/treeowl/orgs","repos_url":"https://api.github.com/users/treeowl/repos","events_url":"https://api.github.com/users/treeowl/events{/privacy}","received_events_url":"https://api.github.com/users/treeowl/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2015-08-23T19:34:15Z","updated_at":"2015-08-24T18:58:19Z","closed_at":null,"body":"I think something like this should work, with a saner name, but I haven't tested it. I don't know if something like this is available for plans; `PlanT` confuses the heck out of me.\r\n\r\n```haskell\r\nfob :: forall m k o s . Monad m => s -> MachineT (StateT s m) k o -> MachineT m k o\r\nfob s (MachineT m) = MachineT $ do\r\n  (stp, s') <- runStateT m s\r\n  case stp of\r\n    Stop -> return Stop\r\n    Yield o m' -> return $ Yield o (fob s' m')\r\n    Await f k q -> return $ Await (fob s' . f) k (fob s' q)\r\n```"},"comment":{"url":"https://api.github.com/repos/ekmett/machines/issues/comments/134339544","html_url":"https://github.com/ekmett/machines/issues/59#issuecomment-134339544","issue_url":"https://api.github.com/repos/ekmett/machines/issues/59","id":134339544,"user":{"login":"treeowl","id":1893117,"avatar_url":"https://avatars.githubusercontent.com/u/1893117?v=3","gravatar_id":"","url":"https://api.github.com/users/treeowl","html_url":"https://github.com/treeowl","followers_url":"https://api.github.com/users/treeowl/followers","following_url":"https://api.github.com/users/treeowl/following{/other_user}","gists_url":"https://api.github.com/users/treeowl/gists{/gist_id}","starred_url":"https://api.github.com/users/treeowl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/treeowl/subscriptions","organizations_url":"https://api.github.com/users/treeowl/orgs","repos_url":"https://api.github.com/users/treeowl/repos","events_url":"https://api.github.com/users/treeowl/events{/privacy}","received_events_url":"https://api.github.com/users/treeowl/received_events","type":"User","site_admin":false},"created_at":"2015-08-24T18:58:19Z","updated_at":"2015-08-24T18:58:19Z","body":"We can also port some exception handling from `pipes`. I think this is probably right:\r\n\r\n```haskell\r\ncatchExcept :: Monad m\r\n               => MachineT (ExceptT e m) k o\r\n               -> (e -> MachineT (ExceptT e m) k o)\r\n               -> MachineT (ExceptT e m) k o\r\ncatchExcept m c =\r\n    MachineT $ do\r\n      step <- E.catchE (runMachineT m) (runMachineT . c)\r\n      case step of\r\n        Stop -> return Stop\r\n        Yield o m' -> return $ Yield o (catchExcept m' c)\r\n        Await f k m' -> return $ Await (flip catchExcept c . f) k (catchExcept m' c)\r\n```\r\nI have the feeling there's some simpler way to handle this."}}