<commit_before>homepage: https://github.com/expede/rescue#readme
changelog-type: ''
hash: 2fd39539e60f7920f829e083fdafd981550bb6e5e38af752692ba4a7b88d44df
test-bench-deps:
  exceptions: -any
  rio: -any
  ghc: -any
  hlint: -any
  rescue: -any
  lens-aeson: -any
  tasty-smallcheck: -any
  base: <5
  hspec: -any
  text: -any
  world-peace: -any
  hspec-core: -any
  tasty-hspec: -any
  criterion: -any
  doctest: -any
  quickcheck-instances: -any
  directory-tree: -any
  mtl: -any
  tasty-hunit: -any
  transformers-base: -any
  tasty-rerun: -any
  transformers: -any
  tasty: -any
  QuickCheck: -any
  Glob: -any
  yaml: -any
  hspec-expectations: -any
  directory: -any
maintainer: <EMAIL>
synopsis: More understandable exceptions
changelog: ''
basic-deps:
  exceptions: -any
  ghc: -any
  base: <5
  text: -any
  world-peace: -any
  mtl: -any
  transformers-base: -any
  transformers: -any
all-versions:
- 0.2.0
- 0.2.1
- 0.3.0
- 0.4.0
author: <NAME>
latest: 0.4.0
description-type: markdown
description: "# \U0001F692✨ Rescue\n## More Understandable Error Handling\n\n![Continuous
  Integration](https://github.com/fission-suite/fission/workflows/Continuous%20Integration/badge.svg)\n![License](https://img.shields.io/github/license/expede/rescue)\n\n`rescue`
  is an experimental error handling library for Haskell.\n\nThe standard library approach
  to error handling is to use an existential type to\n_subclass_ any error as `SomeException`.
  This is very convenient \n(requires nealy zero set up), and matches what  developers
  expect coming from \nother ecosystems.\n\nA core goal of `rescue` is to give the
  programmer clarity about which execptions\nare possible at any given point in the
  code. We achieve this by using (open) variants\nfor compositon rather than inheritance.
  We hide the detail as much as posisble,\nand attempt to make this work in a flexible,
  constraint-driven style as much \nas possible.\n\nPerhaps there is some value in
  treating these more separately. \nThere is an old distinction that mirrors the above
  as errors (irrecoverable) \nvs exceptions (recoverable).\n\n`rescue` breaks the
  problem into synchronous and asynchoronous exceptions.\nThis distinction allows
  us to express our assumptions about the error \nenvironment, separate modes of handling
  for the same monadic stack, \nand even different errors.\n\n# Goals\n\nOur goals
  are to have:\n\n* Clarity of what errors can be raised by some code\n* Not need
  a large tree of error types for our application (set-like)\n* Way to declare assumptions
  about which errrors are available\n  * e.g. \"can raise X, Y, and Z\", or \"raises
  exactly X and Y but none others\"\n* Extensible\n* Ability to call code that raises
  some subset of errors\n* Handle (and eliminate) exceptions from the context\n\n#
  Approach\n\nThe closest approach is `MonadError`, except that our implementation
  uses \ntype-level lists for flexiblity,  and hides the exception parameter from
  the \nclass constraint as a type family.  `rescue` also splits `raise` and `attempt`
  \ninto separate classes to help us more granularly express the effects available
  \nin the current context. \n\n## Class Heirarchy\n\n1. `MonadRaise` -- roughly `MonadThrow`\n2.
  `MonadRescue` -- roughly `MonadCatch`\n3. `MonadCleanup` -- roughly `MonadBracket`\n\n`Monad
  m => MonadRaise m => MonadRescue m => MonadCleanup m`\n\n## Errors / Asynchronous
  Exceptions\n\nAn asynchronous error (e.g. coming from another thread)\ncomes with
  a lot more uncertainty. We may not be aware of the type of error\nbeing thrown to
  us, or when it's thrown (since the runtime will interrupt).\nThe purpose of this
  scenraio is typically to cleanup some resource \nand immeditely rethrow.\n\nWhile
  a more structured, type-driven style would be appreciated here, this is\nfundamentally
  how the runtime works. As such, we do need to contend \nwith `SomeAsyncException`s.\n\nThe
  good news is that we're not expected to do much with them. Essentially all\nwe care
  about is:\n\n* _That_ an async exception interrupted our flow, \n* We should not
  attempt recovery\n* The error should be rethrown\n\nCleanup is also a use case for
  synchronous exceptions. If something is thrown\ninside a context with an open resource,
  we should clean that up.\n\nThe basic flow for an async execption is then:\n\n1.
  An async exception is raised\n2. Convert it to a synchronous exception \n3. Run
  the normal cleanup\n4. Rethrow the original asynchronous error\n\nThis means that
  any instacne of MonadAsyncCleanup needs a MonadCleanup and `Raises m SomeAsyncException`\n\n#
  FAQ\n\n## Why another typeclass?\n\nIt's true that MonadThrow is totally pervasive.
  However, not trying to \n\nThere's also nothing stopping us from writing a function
  of the type\n\n```haskell\nfromThrow :: (MonadCatch m, MonadRaise n) => m a -> n
  a\n```\n\n...though the conversion from `SomeException` would take a bit of care.\n\n##
  Why avoid `SomeException`?\n\n`SomeException` is typesafe, but very difficult to
  track by hand.\nIn fact, with async exceptions, you may need to handle an error
  interrupting\nyour execution _even if you don't have a `MonadThrow`_ in your context.\n\nBy
  treating exceptions as something visible and tarckable (though hidden\nwhen you
  don't need it), we gain a lot of ability to reason about our program,\nand avoid
  writing lots of nested `Either`s.\n\n## Does this do async exception handling?\n\nIt
  does! `MonadCleanup` is the typeclass, and it has very few instances.\nIt's essentially
  [`MonadBracket`](https://www.fpcomplete.com/blog/2017/02/monadmask-vs-monadbracket/),\nbut
  with explicit errors.\n\nThis separation of the `SomeException` and `OpenUnion`
  can help determine the\nintention of the exception. `SomeException` (and `SomeAsyncException`)
  are really\nmore like errors -- things that should fail and not be recovered from.
  In a world\nwith async exceptions, the cleanest way to respond to an error is to
  stop\nour execution, cleanup any resources, and propogate the error.\n\n## Are there
  other packages attempting to solve this problem?\n\nYep! For instance, [`safe-exceptions`](https://hackage.haskell.org/package/safe-exceptions).\nThey
  distinguish between three kinds of exceptions:\n\n> We're going to define three
  different versions of exceptions. Note that these definitions are based on how the
  exception is thrown, not based on what the exception itself is:\n>\n>    **Synchronous**
  exceptions are generated by the current thread. What's important about these is
  that we generally want to be able to recover from them. For example, if you try
  to read from a file, and the file doesn't exist, you may wish to use some default
  value instead of having your program exit, or perhaps prompt the user for a different
  file location.\n>\n>    **Asynchronous** exceptions are thrown by either a different
  user thread, or by the runtime system itself. For example, in the async package,
  race will kill the longer-running thread with an asynchronous exception. Similarly,
  the timeout function will kill an action which has run for too long. And the runtime
  system will kill threads which appear to be deadlocked on MVars or STM actions.\n>\n>
  \   In contrast to synchronous exceptions, we almost never want to recover from
  asynchronous exceptions. In fact, this is a common mistake in Haskell code, and
  from what I've seen has been the largest source of confusion and concern amongst
  users when it comes to Haskell's runtime exception system.\n\n>    **Impure** exceptions
  are hidden inside a pure value, and exposed by forcing evaluation of that value.
  Examples are error, undefined, and impureThrow. Additionally, incomplete pattern
  matches can generate impure exceptions. Ultimately, when these pure values are forced
  and the exception is exposed, it is thrown as a synchronous exception.\n>\n>    Since
  they are ultimately thrown as synchronous exceptions, when it comes to handling
  them, we want to treat them in all ways like synchronous exceptions. Based on the
  comments above, that means we want to be able to recover from impure exceptions.\n\n...along
  with some general guidance...\n\n>   All synchronous exceptions should be recoverable\n>
  \  All asynchronous exceptions should not be recoverable\n>   In both cases, cleanup
  code needs to work reliably\n\nRescue is primarily focused on deligering a great
  experince when dealing with \nsynchronous excpetions, though touches on async ones
  as well. \n"
license-name: Apache-2.0
<commit_msg>Update from Hackage at 2021-03-14T07:50:06Z<commit_after>homepage: https://github.com/expede/rescue#readme
changelog-type: ''
hash: 81f7fcae69cf08937a4ddf7d55d1145d0377e5fbecf6805f81c4d8503a489885
test-bench-deps:
  exceptions: -any
  rio: -any
  ghc: -any
  hlint: -any
  rescue: -any
  lens-aeson: -any
  tasty-smallcheck: -any
  base: <5
  hspec: -any
  text: -any
  world-peace: -any
  hspec-core: -any
  tasty-hspec: -any
  criterion: -any
  doctest: -any
  quickcheck-instances: -any
  directory-tree: -any
  mtl: -any
  tasty-hunit: -any
  transformers-base: -any
  tasty-rerun: -any
  transformers: -any
  tasty: -any
  QuickCheck: -any
  Glob: -any
  yaml: -any
  hspec-expectations: -any
  directory: -any
maintainer: <EMAIL>
synopsis: More understandable exceptions
changelog: ''
basic-deps:
  exceptions: -any
  ghc: -any
  base: <5
  text: -any
  world-peace: -any
  mtl: -any
  transformers-base: -any
  transformers: -any
all-versions:
- 0.2.0
- 0.2.1
- 0.3.0
- 0.4.0
- 0.4.1
author: <NAME>
latest: 0.4.1
description-type: markdown
description: "# \U0001F692✨ Rescue\n## More Understandable Error Handling\n\n![Continuous
  Integration](https://github.com/fission-suite/fission/workflows/Continuous%20Integration/badge.svg)\n![License](https://img.shields.io/github/license/expede/rescue)\n\n`rescue`
  is an experimental error handling library for Haskell.\n\nThe standard library approach
  to error handling is to use an existential type to\n_subclass_ any error as `SomeException`.
  This is very convenient \n(requires nealy zero set up), and matches what  developers
  expect coming from \nother ecosystems.\n\nA core goal of `rescue` is to give the
  programmer clarity about which execptions\nare possible at any given point in the
  code. We achieve this by using (open) variants\nfor compositon rather than inheritance.
  We hide the detail as much as posisble,\nand attempt to make this work in a flexible,
  constraint-driven style as much \nas possible.\n\nPerhaps there is some value in
  treating these more separately. \nThere is an old distinction that mirrors the above
  as errors (irrecoverable) \nvs exceptions (recoverable).\n\n`rescue` breaks the
  problem into synchronous and asynchoronous exceptions.\nThis distinction allows
  us to express our assumptions about the error \nenvironment, separate modes of handling
  for the same monadic stack, \nand even different errors.\n\n# Goals\n\nOur goals
  are to have:\n\n* Clarity of what errors can be raised by some code\n* Not need
  a large tree of error types for our application (set-like)\n* Way to declare assumptions
  about which errrors are available\n  * e.g. \"can raise X, Y, and Z\", or \"raises
  exactly X and Y but none others\"\n* Extensible\n* Ability to call code that raises
  some subset of errors\n* Handle (and eliminate) exceptions from the context\n\n#
  Approach\n\nThe closest approach is `MonadError`, except that our implementation
  uses \ntype-level lists for flexiblity,  and hides the exception parameter from
  the \nclass constraint as a type family.  `rescue` also splits `raise` and `attempt`
  \ninto separate classes to help us more granularly express the effects available
  \nin the current context. \n\n## Class Heirarchy\n\n1. `MonadRaise` -- roughly `MonadThrow`\n2.
  `MonadRescue` -- roughly `MonadCatch`\n3. `MonadCleanup` -- roughly `MonadBracket`\n\n`Monad
  m => MonadRaise m => MonadRescue m => MonadCleanup m`\n\n## Errors / Asynchronous
  Exceptions\n\nAn asynchronous error (e.g. coming from another thread)\ncomes with
  a lot more uncertainty. We may not be aware of the type of error\nbeing thrown to
  us, or when it's thrown (since the runtime will interrupt).\nThe purpose of this
  scenraio is typically to cleanup some resource \nand immeditely rethrow.\n\nWhile
  a more structured, type-driven style would be appreciated here, this is\nfundamentally
  how the runtime works. As such, we do need to contend \nwith `SomeAsyncException`s.\n\nThe
  good news is that we're not expected to do much with them. Essentially all\nwe care
  about is:\n\n* _That_ an async exception interrupted our flow, \n* We should not
  attempt recovery\n* The error should be rethrown\n\nCleanup is also a use case for
  synchronous exceptions. If something is thrown\ninside a context with an open resource,
  we should clean that up.\n\nThe basic flow for an async execption is then:\n\n1.
  An async exception is raised\n2. Convert it to a synchronous exception \n3. Run
  the normal cleanup\n4. Rethrow the original asynchronous error\n\nThis means that
  any instacne of MonadAsyncCleanup needs a MonadCleanup and `Raises m SomeAsyncException`\n\n#
  FAQ\n\n## Why another typeclass?\n\nIt's true that MonadThrow is totally pervasive.
  However, not trying to \n\nThere's also nothing stopping us from writing a function
  of the type\n\n```haskell\nfromThrow :: (MonadCatch m, MonadRaise n) => m a -> n
  a\n```\n\n...though the conversion from `SomeException` would take a bit of care.\n\n##
  Why avoid `SomeException`?\n\n`SomeException` is typesafe, but very difficult to
  track by hand.\nIn fact, with async exceptions, you may need to handle an error
  interrupting\nyour execution _even if you don't have a `MonadThrow`_ in your context.\n\nBy
  treating exceptions as something visible and tarckable (though hidden\nwhen you
  don't need it), we gain a lot of ability to reason about our program,\nand avoid
  writing lots of nested `Either`s.\n\n## Does this do async exception handling?\n\nIt
  does! `MonadCleanup` is the typeclass, and it has very few instances.\nIt's essentially
  [`MonadBracket`](https://www.fpcomplete.com/blog/2017/02/monadmask-vs-monadbracket/),\nbut
  with explicit errors.\n\nThis separation of the `SomeException` and `OpenUnion`
  can help determine the\nintention of the exception. `SomeException` (and `SomeAsyncException`)
  are really\nmore like errors -- things that should fail and not be recovered from.
  In a world\nwith async exceptions, the cleanest way to respond to an error is to
  stop\nour execution, cleanup any resources, and propogate the error.\n\n## Are there
  other packages attempting to solve this problem?\n\nYep! For instance, [`safe-exceptions`](https://hackage.haskell.org/package/safe-exceptions).\nThey
  distinguish between three kinds of exceptions:\n\n> We're going to define three
  different versions of exceptions. Note that these definitions are based on how the
  exception is thrown, not based on what the exception itself is:\n>\n>    **Synchronous**
  exceptions are generated by the current thread. What's important about these is
  that we generally want to be able to recover from them. For example, if you try
  to read from a file, and the file doesn't exist, you may wish to use some default
  value instead of having your program exit, or perhaps prompt the user for a different
  file location.\n>\n>    **Asynchronous** exceptions are thrown by either a different
  user thread, or by the runtime system itself. For example, in the async package,
  race will kill the longer-running thread with an asynchronous exception. Similarly,
  the timeout function will kill an action which has run for too long. And the runtime
  system will kill threads which appear to be deadlocked on MVars or STM actions.\n>\n>
  \   In contrast to synchronous exceptions, we almost never want to recover from
  asynchronous exceptions. In fact, this is a common mistake in Haskell code, and
  from what I've seen has been the largest source of confusion and concern amongst
  users when it comes to Haskell's runtime exception system.\n\n>    **Impure** exceptions
  are hidden inside a pure value, and exposed by forcing evaluation of that value.
  Examples are error, undefined, and impureThrow. Additionally, incomplete pattern
  matches can generate impure exceptions. Ultimately, when these pure values are forced
  and the exception is exposed, it is thrown as a synchronous exception.\n>\n>    Since
  they are ultimately thrown as synchronous exceptions, when it comes to handling
  them, we want to treat them in all ways like synchronous exceptions. Based on the
  comments above, that means we want to be able to recover from impure exceptions.\n\n...along
  with some general guidance...\n\n>   All synchronous exceptions should be recoverable\n>
  \  All asynchronous exceptions should not be recoverable\n>   In both cases, cleanup
  code needs to work reliably\n\nRescue is primarily focused on deligering a great
  experince when dealing with \nsynchronous excpetions, though touches on async ones
  as well. \n"
license-name: Apache-2.0

{'fraction_non_alphanumeric': 0.07791531698287829, 'fraction_numerical': 0.010354002776492365, 'mean_word_length': 3.914440022740193, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 43, 'https://': 10, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2063799', 'n_tokens_mistral': 5297, 'n_tokens_neox': 5069, 'n_words': 2235}