<commit_before>homepage: https://github.com/basvandijk/monad-control
changelog-type: text
hash: 376ae3f6ba84d988e7865dd21bccc5818885d1af517231adc10f6a327b039bfb
test-bench-deps: {}
maintainer: <NAME> <<EMAIL>>
synopsis: Lift control operations, like exception catching, through monad transformers
changelog: ! "1.0.0.4\n\n* Support transformers-compat-0.4.*.\n\n\n1.0.0.3\n\n* Unconditionally
  add ExceptT instances using transformers-compat.\n  Courtesy of Adam Bergmark.\n\n\n1.0.0.2\n\n*
  Add a base >= 4.5 constraint because monad-control only builds on GHC >= 7.4.\n\n\n1.0.0.1\n\n*
  Use Safe instead of Trustworthy.\n\n  This requires a dependency on stm.\n\n\n1.0.0.0\n\n*
  Switch the associated data types StT and StM to associated type synonyms.\n\n  This
  is an API breaking change. To fix your MonadTransControl or\n  MonadBaseControl
  instances simply remove the StT or StM constructors\n  and deconstructors for your
  monad transformers or monad.\n\n* Add the embed, embed_ and liftBaseOpDiscard functions.\n\n\n0.3.3.0\n\n*
  Support transformers-0.4.0.0\n\n* Drop unicode syntax and symbols\n\n\n0.3.2.3\n\n*
  \ Fix haddock documentation error\n\n\n0.3.2.2\n\n*  Fix preprocessor directive
  for GHC 7.6.3\n\n\n0.3.2.1\n\n* Resolve #14. Bump upper version bound of base to
  5\n\n\n0.3.2\n\n* Added defaultLiftWith and defaultRestoreT to simplify defining\n
  \ MonadTransControl for newtypes.\n\n\n0.3.1.4\n\n* Compatibility with ghc head\n\n\n0.3.1.3\n\n*
  Added a Trustworthy flag\n\n\n0.3.1.2\n\n* Fix issue #9. Replace all Unicode in
  type variables.\n\n\n0.3.1.1\n\n* Add MonadBaseControl instances for ST and STM.\n\n\n0.3\n\n(Released
  on: Fri Dec 2 09:52:16 UTC 2011)\n\n* Major new API which IMHO is easier to understand
  than the old one.\n\n* On average about 60 times faster than the previous release!\n\n*
  New package lifted-base providing lifted versions of functions from the base\n  library.
  It exports the following modules:\n\n  - Control.Exception.Lifted\n  - Control.Concurrent.Lifted\n
  \ - Control.Concurrent.MVar.Lifted\n  - System.Timeout.Lifted\n\n  Not all modules
  from base are converted yet. If you need a lifted version of\n  some function from
  base, just ask me to add it or send me a patch.\n\n\n0.2.0.3\n\n(Released on: Sat
  Aug 27 21:18:22 UTC 2011)\n\n* Fixed issue #2\n  https://github.com/basvandijk/monad-control/issues/2\n\n\n0.2.0.2\n\n(Released
  on: Mon Aug 8 09:16:08 UTC 2011)\n\n* Switched to git on github.\n\n* Tested with
  base-4.4 and ghc-7.2.1.\n\n* Use the new cabal test-suite feature.\n\n\n0.2.0.1\n\n(Released
  on: Wed Mar 16 15:53:50 UTC 2011)\n\n* Added laws for MonadTransControl and MonadControlIO\n\n*
  Bug fix: Add proper laziness to the MonadTransControl instances\n  of the lazy StateT,
  WriteT and RWST\n  These all failed the law: control $ \\run -> run t = t\n  where
  t = return undefined\n\n* Add INLINABLE pragmas for most public functions\n  A simple
  benchmark showed some functions\n  (bracket and mask) improving by 30%.\n\n\n0.2\n\n(Released
  on: Wed Feb 9 12:05:26 UTC 2011)\n\n* Use RunInBase in the type of idLiftControl.\n\n*
  Added this NEWS file.\n\n* Only parameterize Run with t and use RankNTypes to quantify
  n and o\n  -liftControl :: (Monad m, Monad n, Monad o) => (Run t n o -> m a) ->
  t m a\n  +liftControl :: Monad m => (Run t -> m a) -> t m a\n\n  -type Run t n o
  = forall b. t n b -> n (t o b)\n  +type Run t = forall n o b. (Monad n, Monad o,
  Monad (t o)) => t n b -> n (t o b)\n\n  Bumped version from 0.1 to 0.2 to indicate
  this breaking change in API.\n\n* Added example of a derivation of liftControlIO.\n
  \ Really enlightening!\n\n\n0.1\n\n(Released on: Sat Feb 5 23:36:21 UTC 2011)\n\n*
  Initial release\n\nThis is the announcement message sent to the Haskell mailinglists:\nhttp://www.mail-archive.com/<EMAIL>/msg23278.html\n\n\nDear
  all,\n\nSeveral attempts have been made to lift control operations (functions\nthat
  use monadic actions as input instead of just output) through\nmonad transformers:\n\nMonadCatchIO-transformers[1]
  provided a type class that allowed to\noverload some often used control operations
  (catch, block and\nunblock). Unfortunately that library was limited to those operations.\nIt
  was not possible to use, say, alloca in a monad transformer. More\nimportantly however,
  the library was broken as was explained[2] by\n<NAME>. In response Michael
  created the MonadInvertIO type\nclass which solved the problems. Then <NAME>
  created the\nmonad-peel library which provided an even nicer implementation.\n\nmonad-control
  is a rewrite of monad-peel that uses CPS style\noperations and exploits the RankNTypes
  language extension to simplify\nand speedup most functions. A very preliminary and
  not yet fully\nrepresentative, benchmark shows that monad-control is on average
  about\n2.6 times faster than monad-peel:\n\nbracket:  2.4 x faster\nbracket_: 3.1
  x faster\ncatch:    1.8 x faster\ntry:      4.0 x faster\nmask:     2.0 x faster\n\nNote
  that, although the package comes with a test suite that passes, I\nstill consider
  it highly experimental.\n\n\nAPI DOCS:\n\nhttp://hackage.haskell.org/package/monad-control\n\n\nINSTALLING:\n\n$
  cabal update\n$ cabal install monad-control\n\n\nTESTING:\n\nThe package contains
  a copy of the monad-peel test suite written by\nAnders. You can perform the tests
  using:\n\n$ cabal unpack monad-control\n$ cd monad-control\n$ cabal configure -ftest\n$
  cabal test\n\n\nBENCHMARKING:\n\n$ darcs get http://bifunctor.homelinux.net/~bas/bench-monad-peel-control/\n$
  cd bench-monad-peel-control\n$ cabal configure\n$ cabal build\n$ dist/build/bench-monad-peel-control/bench-monad-peel-control\n\n\nDEVELOPING:\n\nThe
  darcs repository will be hosted on code.haskell.org ones that\nserver is back online.
  For the time being you can get the repository\nfrom:\n\n$ darcs get http://bifunctor.homelinux.net/~bas/monad-control/\n\n\nTUTORIAL:\n\nThis
  short unpolished tutorial will explain how to lift control\noperations through monad
  transformers. Our goal is to lift a control\noperation like:\n\nfoo ∷ M a → M a\n\nwhere
  M is some monad, into a transformed monad like 'StateT M':\n\nfoo' ∷ StateT M a
  → StateT M a\n\nThe first thing we need to do is write an instance for the\nMonadTransControl
  type class:\n\nclass MonadTrans t ⇒ MonadTransControl t where\n  liftControl ∷ (Monad
  m, Monad n, Monad o)\n              ⇒ (Run t n o → m a) → t m a\n\nIf you ignore
  the Run argument for now, you'll see that liftControl is\nidentical to the 'lift'
  method of the MonadTrans type class:\n\nclass MonadTrans t where\n    lift ∷ Monad
  m ⇒ m a → t m a\n\nSo the instance for MonadTransControl will probably look very
  much\nlike the instance for MonadTrans. Let's see:\n\ninstance MonadTransControl
  (StateT s) where\n    liftControl f = StateT $ \\s → liftM (\\x → (x, s)) (f run)\n\nSo
  what is this run function? Let's look at its type:\n\ntype Run t n o = ∀ b. t n
  b → n (t o b)\n\nThe run function executes a transformed monadic action 't n b'
  in the\nnon-transformed monad 'n'. In our case the 't' will be a StateT\ncomputation.
  The only way to run a StateT computation is to give it\nsome state and the only
  state we have lying around is the one from the\nouter computation: 's'. So let's
  run it on 's':\n\ninstance MonadTransControl (StateT s) where\n    liftControl f
  =\n        StateT $ \\s →\n          let run t = ... runStateT t s ...\n          in
  liftM (\\x → (x, s)) (f run)\n\nNow that we are able to run a transformed monadic
  action, we're almost\ndone. Look at the type of Run again. The function should leave
  the\nresult 't o b' in the monad 'n'. This 't o b' computation should\ncontain the
  final state after running the supplied 't n b'\ncomputation. In case of our StateT
  it should contain the final state\ns':\n\ninstance MonadTransControl (StateT s)
  where\n    liftControl f =\n        StateT $ \\s →\n          let run t = liftM
  (\\(x, s') → StateT $ \\_ → return (x, s'))\n                            (runStateT
  t s)\n          in liftM (\\x → (x, s)) (f run)\n\nThis final computation, \"StateT
  $ \\_ → return (x, s')\", can later be\nused to restore the final state. Now that
  we have our\nMonadTransControl instance we can start using it. Recall that our goal\nwas
  to lift \"foo ∷ M a → M a\" into our StateT transformer yielding the\nfunction \"foo'
  ∷ StateT M a → StateT M a\".\n\nTo define foo', the first thing we need to do is
  call liftControl:\n\nfoo' t = liftControl $ \\run → ...\n\nThis captures the current
  state of the StateT computation and provides\nus with the run function that allows
  us to run a StateT computation on\nthis captured state.\n\nNow recall the type of
  liftControl ∷ (Run t n o → m a) → t m a. You\ncan see that in place of the ... we
  must fill in a value of type 'm\na'. In our case this will be a value of type 'M
  a'. We can construct\nsuch a value by calling foo. However, foo expects an argument
  of type\n'M a'. Fortunately we can provide one if we convert the supplied 't'\ncomputation
  of type 'StateT M a' to 'M a' using our run function of\ntype ∀ b. StateT M b →
  M (StateT o b):\n\nfoo' t = ... liftControl $ \\run → foo $ run t\n\nHowever, note
  that the run function returns the final StateT\ncomputation inside M. So the type
  of the right hand side is now\n'StateT M (StateT o b)'. We would like to restore
  this final state. We\ncan do that using join:\n\nfoo' t = join $ liftControl $ \\run
  → foo $ run t\n\nThat's it! Note that because it's so common to join after a\nliftControl
  I provide an abstraction for it:\n\ncontrol = join ∘ liftControl\n\nAllowing you
  to simplify foo' to:\n\nfoo' t = control $ \\run → foo $ run t\n\nProbably the most
  common control operations that you want to lift\nthrough your transformers are IO
  operations. Think about: bracket,\nalloca, mask, etc.. For this reason I provide
  the MonadControlIO type\nclass:\n\nclass MonadIO m ⇒ MonadControlIO m where\n  liftControlIO
  ∷ (RunInBase m IO → IO a) → m a\n\nAgain, if you ignore the RunInBase argument,
  you will see that\nliftControlIO is identical to the liftIO method of the MonadIO
  type\nclass:\n\nclass Monad m ⇒ MonadIO m where\n    liftIO ∷ IO a → m a\n\nJust
  like Run, RunInBase allows you to run your monadic computation\ninside your base
  monad, which in case of liftControlIO is IO:\n\ntype RunInBase m base = ∀ b. m b
  → base (m b)\n\nThe instance for the base monad is trivial:\n\ninstance MonadControlIO
  IO where\n    liftControlIO = idLiftControl\n\nidLiftControl directly executes f
  and passes it a run function which\nexecutes the given action and lifts the result
  r into the trivial\n'return r' action:\n\nidLiftControl ∷ Monad m ⇒ ((∀ b. m b →
  m (m b)) → m a) → m a\nidLiftControl f = f $ liftM $ \\r -> return r\n\nThe instances
  for the transformers are all identical. Let's look at\nStateT and ReaderT:\n\ninstance
  MonadControlIO m ⇒ MonadControlIO (StateT s m) where\n    liftControlIO = liftLiftControlBase
  liftControlIO\n\ninstance MonadControlIO m ⇒ MonadControlIO (ReaderT r m) where\n
  \   liftControlIO = liftLiftControlBase liftControlIO\n\nThe magic function is liftLiftControlBase.
  This function is used to\ncompose two liftControl operations, the outer provided
  by a\nMonadTransControl instance and the inner provided as the argument:\n\nliftLiftControlBase
  ∷ (MonadTransControl t, Monad base, Monad m, Monad (t m))\n                    ⇒
  ((RunInBase m     base → base a) →   m a)\n                    → ((RunInBase (t
  m) base → base a) → t m a)\nliftLiftControlBase lftCtrlBase =\n  \\f → liftControl
  $ \\run →\n         lftCtrlBase $ \\runInBase →\n           f $ liftM (join ∘ lift)
  ∘ runInBase ∘ run\n\nBasically it captures the state of the outer monad transformer
  using\nliftControl. Then it captures the state of the inner monad using the\nsupplied
  lftCtrlBase function. If you recall the identical definitions\nof the liftControlIO
  methods: 'liftLiftControlBase liftControlIO' you\nwill see that this lftCtrlBase
  function is the recursive step of\nliftLiftControlBase. If you use 'liftLiftControlBase
  liftControlIO' in\na stack of monad transformers a chain of liftControl operations
  is\ncreated:\n\nliftControl $ \\run1 -> liftControl $ \\run2 -> liftControl $ \\run3
  -> ...\n\nThis will recurse until we hit the base monad. Then\nliftLiftControlBase
  will finally run f in the base monad supplying it\nwith a run function that is able
  to run a 't m a' computation in the\nbase monad. It does this by composing the run
  and runInBase functions.\nNote that runInBase is basically the composition: '...
  ∘ run3 ∘ run2'.\n\nHowever, just composing the run and runInBase functions is not
  enough.\nNamely: runInBase ∘ run ∷ ∀ b. t m b → base (m (t m b)) while we need\nto
  have ∀ b. t m b → base (t m b). So we need to lift the 'm (t m b)'\ncomputation
  inside t yielding: 't m (t m b)' and then join that to get\n't m b'.\n\nNow that
  we have our MonadControlIO instances we can start using them.\nLet's look at how
  to lift 'bracket' into a monad supporting\nMonadControlIO. Before we do that I define
  a little convenience\nfunction similar to 'control':\n\ncontrolIO = join ∘ liftControlIO\n\nBracket
  just calls controlIO which captures the state of m and\nprovides us with a runInIO
  function which allows us to run an m\ncomputation in IO:\n\nbracket ∷ MonadControlIO
  m\n        ⇒ m a → (a → m b) → (a → m c) → m c\nbracket before after thing =\n  controlIO
  $ \\runInIO →\n    E.bracket (runInIO before)\n              (\\m → runInIO $ m
  >>= after)\n              (\\m → runInIO $ m >>= thing)\n\nI welcome any comments,
  questions or patches.\n\nRegards,\n\nBas\n\n[1] http://hackage.haskell.org/package/MonadCatchIO-transformers\n[2]
  http://docs.yesodweb.com/blog/invertible-monads-exceptions-allocations/\n[3] http://hackage.haskell.org/package/monad-peel\n"
basic-deps:
  stm: ! '>=2.3 && <3'
  base: ! '>=4.5 && <5'
  transformers-base: ! '>=0.4.4 && <0.5'
  transformers: ! '>=0.2 && <0.5'
  transformers-compat: ! '>=0.3 && <0.5'
all-versions:
- '0.1'
- '0.2'
- '0.2.0.1'
- '0.2.0.2'
- '0.2.0.3'
- '0.3'
- '0.3.0.1'
- '0.3.1'
- '0.3.1.1'
- '0.3.1.2'
- '0.3.1.3'
- '0.3.1.4'
- '0.3.2'
- '0.3.2.1'
- '0.3.2.2'
- '0.3.2.3'
- '0.3.3.0'
- '0.3.3.1'
- '1.0.0.0'
- '1.0.0.1'
- '1.0.0.2'
- '1.0.0.3'<commit_msg>Update from Hackage at 2016-01-24T11:41:31+0000<commit_after>homepage: https://github.com/basvandijk/monad-control
changelog-type: text
hash: 2df3fbea3354b0d5e0faefe0c441b7d5485a5669caec28a5d9643c15c47c7e76
test-bench-deps: {}
maintainer: <NAME> <<EMAIL>>
synopsis: Lift control operations, like exception catching, through monad transformers
changelog: ! "1.0.0.4\n\n* Support transformers-compat-0.4.*.\n\n\n1.0.0.3\n\n* Unconditionally
  add ExceptT instances using transformers-compat.\n  Courtesy of <NAME>.\n\n\n1.0.0.2\n\n*
  Add a base >= 4.5 constraint because monad-control only builds on GHC >= 7.4.\n\n\n1.0.0.1\n\n*
  Use Safe instead of Trustworthy.\n\n  This requires a dependency on stm.\n\n\n1.0.0.0\n\n*
  Switch the associated data types StT and StM to associated type synonyms.\n\n  This
  is an API breaking change. To fix your MonadTransControl or\n  MonadBaseControl
  instances simply remove the StT or StM constructors\n  and deconstructors for your
  monad transformers or monad.\n\n* Add the embed, embed_ and liftBaseOpDiscard functions.\n\n\n0.3.3.0\n\n*
  Support transformers-0.4.0.0\n\n* Drop unicode syntax and symbols\n\n\n0.3.2.3\n\n*
  \ Fix haddock documentation error\n\n\n0.3.2.2\n\n*  Fix preprocessor directive
  for GHC 7.6.3\n\n\n0.3.2.1\n\n* Resolve #14. Bump upper version bound of base to
  5\n\n\n0.3.2\n\n* Added defaultLiftWith and defaultRestoreT to simplify defining\n
  \ MonadTransControl for newtypes.\n\n\n0.3.1.4\n\n* Compatibility with ghc head\n\n\n0.3.1.3\n\n*
  Added a Trustworthy flag\n\n\n0.3.1.2\n\n* Fix issue #9. Replace all Unicode in
  type variables.\n\n\n0.3.1.1\n\n* Add MonadBaseControl instances for ST and STM.\n\n\n0.3\n\n(Released
  on: Fri Dec 2 09:52:16 UTC 2011)\n\n* Major new API which IMHO is easier to understand
  than the old one.\n\n* On average about 60 times faster than the previous release!\n\n*
  New package lifted-base providing lifted versions of functions from the base\n  library.
  It exports the following modules:\n\n  - Control.Exception.Lifted\n  - Control.Concurrent.Lifted\n
  \ - Control.Concurrent.MVar.Lifted\n  - System.Timeout.Lifted\n\n  Not all modules
  from base are converted yet. If you need a lifted version of\n  some function from
  base, just ask me to add it or send me a patch.\n\n\n0.2.0.3\n\n(Released on: Sat
  Aug 27 21:18:22 UTC 2011)\n\n* Fixed issue #2\n  https://github.com/basvandijk/monad-control/issues/2\n\n\n0.2.0.2\n\n(Released
  on: Mon Aug 8 09:16:08 UTC 2011)\n\n* Switched to git on github.\n\n* Tested with
  base-4.4 and ghc-7.2.1.\n\n* Use the new cabal test-suite feature.\n\n\n0.2.0.1\n\n(Released
  on: Wed Mar 16 15:53:50 UTC 2011)\n\n* Added laws for MonadTransControl and MonadControlIO\n\n*
  Bug fix: Add proper laziness to the MonadTransControl instances\n  of the lazy StateT,
  WriteT and RWST\n  These all failed the law: control $ \\run -> run t = t\n  where
  t = return undefined\n\n* Add INLINABLE pragmas for most public functions\n  A simple
  benchmark showed some functions\n  (bracket and mask) improving by 30%.\n\n\n0.2\n\n(Released
  on: Wed Feb 9 12:05:26 UTC 2011)\n\n* Use RunInBase in the type of idLiftControl.\n\n*
  Added this NEWS file.\n\n* Only parameterize Run with t and use RankNTypes to quantify
  n and o\n  -liftControl :: (Monad m, Monad n, Monad o) => (Run t n o -> m a) ->
  t m a\n  +liftControl :: Monad m => (Run t -> m a) -> t m a\n\n  -type Run t n o
  = forall b. t n b -> n (t o b)\n  +type Run t = forall n o b. (Monad n, Monad o,
  Monad (t o)) => t n b -> n (t o b)\n\n  Bumped version from 0.1 to 0.2 to indicate
  this breaking change in API.\n\n* Added example of a derivation of liftControlIO.\n
  \ Really enlightening!\n\n\n0.1\n\n(Released on: Sat Feb 5 23:36:21 UTC 2011)\n\n*
  Initial release\n\nThis is the announcement message sent to the Haskell mailinglists:\nhttp://www.mail-archive.com/haskell@haskell.org/msg23278.html\n\n\nDear
  all,\n\nSeveral attempts have been made to lift control operations (functions\nthat
  use monadic actions as input instead of just output) through\nmonad transformers:\n\nMonadCatchIO-transformers[1]
  provided a type class that allowed to\noverload some often used control operations
  (catch, block and\nunblock). Unfortunately that library was limited to those operations.\nIt
  was not possible to use, say, alloca in a monad transformer. More\nimportantly however,
  the library was broken as was explained[2] by\n<NAME>. In response Michael
  created the MonadInvertIO type\nclass which solved the problems. Then <NAME>
  created the\nmonad-peel library which provided an even nicer implementation.\n\nmonad-control
  is a rewrite of monad-peel that uses CPS style\noperations and exploits the RankNTypes
  language extension to simplify\nand speedup most functions. A very preliminary and
  not yet fully\nrepresentative, benchmark shows that monad-control is on average
  about\n2.6 times faster than monad-peel:\n\nbracket:  2.4 x faster\nbracket_: 3.1
  x faster\ncatch:    1.8 x faster\ntry:      4.0 x faster\nmask:     2.0 x faster\n\nNote
  that, although the package comes with a test suite that passes, I\nstill consider
  it highly experimental.\n\n\nAPI DOCS:\n\nhttp://hackage.haskell.org/package/monad-control\n\n\nINSTALLING:\n\n$
  cabal update\n$ cabal install monad-control\n\n\nTESTING:\n\nThe package contains
  a copy of the monad-peel test suite written by\nAnders. You can perform the tests
  using:\n\n$ cabal unpack monad-control\n$ cd monad-control\n$ cabal configure -ftest\n$
  cabal test\n\n\nBENCHMARKING:\n\n$ darcs get http://bifunctor.homelinux.net/~bas/bench-monad-peel-control/\n$
  cd bench-monad-peel-control\n$ cabal configure\n$ cabal build\n$ dist/build/bench-monad-peel-control/bench-monad-peel-control\n\n\nDEVELOPING:\n\nThe
  darcs repository will be hosted on code.haskell.org ones that\nserver is back online.
  For the time being you can get the repository\nfrom:\n\n$ darcs get http://bifunctor.homelinux.net/~bas/monad-control/\n\n\nTUTORIAL:\n\nThis
  short unpolished tutorial will explain how to lift control\noperations through monad
  transformers. Our goal is to lift a control\noperation like:\n\nfoo ∷ M a → M a\n\nwhere
  M is some monad, into a transformed monad like 'StateT M':\n\nfoo' ∷ StateT M a
  → StateT M a\n\nThe first thing we need to do is write an instance for the\nMonadTransControl
  type class:\n\nclass MonadTrans t ⇒ MonadTransControl t where\n  liftControl ∷ (Monad
  m, Monad n, Monad o)\n              ⇒ (Run t n o → m a) → t m a\n\nIf you ignore
  the Run argument for now, you'll see that liftControl is\nidentical to the 'lift'
  method of the MonadTrans type class:\n\nclass MonadTrans t where\n    lift ∷ Monad
  m ⇒ m a → t m a\n\nSo the instance for MonadTransControl will probably look very
  much\nlike the instance for MonadTrans. Let's see:\n\ninstance MonadTransControl
  (StateT s) where\n    liftControl f = StateT $ \\s → liftM (\\x → (x, s)) (f run)\n\nSo
  what is this run function? Let's look at its type:\n\ntype Run t n o = ∀ b. t n
  b → n (t o b)\n\nThe run function executes a transformed monadic action 't n b'
  in the\nnon-transformed monad 'n'. In our case the 't' will be a StateT\ncomputation.
  The only way to run a StateT computation is to give it\nsome state and the only
  state we have lying around is the one from the\nouter computation: 's'. So let's
  run it on 's':\n\ninstance MonadTransControl (StateT s) where\n    liftControl f
  =\n        StateT $ \\s →\n          let run t = ... runStateT t s ...\n          in
  liftM (\\x → (x, s)) (f run)\n\nNow that we are able to run a transformed monadic
  action, we're almost\ndone. Look at the type of Run again. The function should leave
  the\nresult 't o b' in the monad 'n'. This 't o b' computation should\ncontain the
  final state after running the supplied 't n b'\ncomputation. In case of our StateT
  it should contain the final state\ns':\n\ninstance MonadTransControl (StateT s)
  where\n    liftControl f =\n        StateT $ \\s →\n          let run t = liftM
  (\\(x, s') → StateT $ \\_ → return (x, s'))\n                            (runStateT
  t s)\n          in liftM (\\x → (x, s)) (f run)\n\nThis final computation, \"StateT
  $ \\_ → return (x, s')\", can later be\nused to restore the final state. Now that
  we have our\nMonadTransControl instance we can start using it. Recall that our goal\nwas
  to lift \"foo ∷ M a → M a\" into our StateT transformer yielding the\nfunction \"foo'
  ∷ StateT M a → StateT M a\".\n\nTo define foo', the first thing we need to do is
  call liftControl:\n\nfoo' t = liftControl $ \\run → ...\n\nThis captures the current
  state of the StateT computation and provides\nus with the run function that allows
  us to run a StateT computation on\nthis captured state.\n\nNow recall the type of
  liftControl ∷ (Run t n o → m a) → t m a. You\ncan see that in place of the ... we
  must fill in a value of type 'm\na'. In our case this will be a value of type 'M
  a'. We can construct\nsuch a value by calling foo. However, foo expects an argument
  of type\n'M a'. Fortunately we can provide one if we convert the supplied 't'\ncomputation
  of type 'StateT M a' to 'M a' using our run function of\ntype ∀ b. StateT M b →
  M (StateT o b):\n\nfoo' t = ... liftControl $ \\run → foo $ run t\n\nHowever, note
  that the run function returns the final StateT\ncomputation inside M. So the type
  of the right hand side is now\n'StateT M (StateT o b)'. We would like to restore
  this final state. We\ncan do that using join:\n\nfoo' t = join $ liftControl $ \\run
  → foo $ run t\n\nThat's it! Note that because it's so common to join after a\nliftControl
  I provide an abstraction for it:\n\ncontrol = join ∘ liftControl\n\nAllowing you
  to simplify foo' to:\n\nfoo' t = control $ \\run → foo $ run t\n\nProbably the most
  common control operations that you want to lift\nthrough your transformers are IO
  operations. Think about: bracket,\nalloca, mask, etc.. For this reason I provide
  the MonadControlIO type\nclass:\n\nclass MonadIO m ⇒ MonadControlIO m where\n  liftControlIO
  ∷ (RunInBase m IO → IO a) → m a\n\nAgain, if you ignore the RunInBase argument,
  you will see that\nliftControlIO is identical to the liftIO method of the MonadIO
  type\nclass:\n\nclass Monad m ⇒ MonadIO m where\n    liftIO ∷ IO a → m a\n\nJust
  like Run, RunInBase allows you to run your monadic computation\ninside your base
  monad, which in case of liftControlIO is IO:\n\ntype RunInBase m base = ∀ b. m b
  → base (m b)\n\nThe instance for the base monad is trivial:\n\ninstance MonadControlIO
  IO where\n    liftControlIO = idLiftControl\n\nidLiftControl directly executes f
  and passes it a run function which\nexecutes the given action and lifts the result
  r into the trivial\n'return r' action:\n\nidLiftControl ∷ Monad m ⇒ ((∀ b. m b →
  m (m b)) → m a) → m a\nidLiftControl f = f $ liftM $ \\r -> return r\n\nThe instances
  for the transformers are all identical. Let's look at\nStateT and ReaderT:\n\ninstance
  MonadControlIO m ⇒ MonadControlIO (StateT s m) where\n    liftControlIO = liftLiftControlBase
  liftControlIO\n\ninstance MonadControlIO m ⇒ MonadControlIO (ReaderT r m) where\n
  \   liftControlIO = liftLiftControlBase liftControlIO\n\nThe magic function is liftLiftControlBase.
  This function is used to\ncompose two liftControl operations, the outer provided
  by a\nMonadTransControl instance and the inner provided as the argument:\n\nliftLiftControlBase
  ∷ (MonadTransControl t, Monad base, Monad m, Monad (t m))\n                    ⇒
  ((RunInBase m     base → base a) →   m a)\n                    → ((RunInBase (t
  m) base → base a) → t m a)\nliftLiftControlBase lftCtrlBase =\n  \\f → liftControl
  $ \\run →\n         lftCtrlBase $ \\runInBase →\n           f $ liftM (join ∘ lift)
  ∘ runInBase ∘ run\n\nBasically it captures the state of the outer monad transformer
  using\nliftControl. Then it captures the state of the inner monad using the\nsupplied
  lftCtrlBase function. If you recall the identical definitions\nof the liftControlIO
  methods: 'liftLiftControlBase liftControlIO' you\nwill see that this lftCtrlBase
  function is the recursive step of\nliftLiftControlBase. If you use 'liftLiftControlBase
  liftControlIO' in\na stack of monad transformers a chain of liftControl operations
  is\ncreated:\n\nliftControl $ \\run1 -> liftControl $ \\run2 -> liftControl $ \\run3
  -> ...\n\nThis will recurse until we hit the base monad. Then\nliftLiftControlBase
  will finally run f in the base monad supplying it\nwith a run function that is able
  to run a 't m a' computation in the\nbase monad. It does this by composing the run
  and runInBase functions.\nNote that runInBase is basically the composition: '...
  ∘ run3 ∘ run2'.\n\nHowever, just composing the run and runInBase functions is not
  enough.\nNamely: runInBase ∘ run ∷ ∀ b. t m b → base (m (t m b)) while we need\nto
  have ∀ b. t m b → base (t m b). So we need to lift the 'm (t m b)'\ncomputation
  inside t yielding: 't m (t m b)' and then join that to get\n't m b'.\n\nNow that
  we have our MonadControlIO instances we can start using them.\nLet's look at how
  to lift 'bracket' into a monad supporting\nMonadControlIO. Before we do that I define
  a little convenience\nfunction similar to 'control':\n\ncontrolIO = join ∘ liftControlIO\n\nBracket
  just calls controlIO which captures the state of m and\nprovides us with a runInIO
  function which allows us to run an m\ncomputation in IO:\n\nbracket ∷ MonadControlIO
  m\n        ⇒ m a → (a → m b) → (a → m c) → m c\nbracket before after thing =\n  controlIO
  $ \\runInIO →\n    E.bracket (runInIO before)\n              (\\m → runInIO $ m
  >>= after)\n              (\\m → runInIO $ m >>= thing)\n\nI welcome any comments,
  questions or patches.\n\nRegards,\n\nBas\n\n[1] http://hackage.haskell.org/package/MonadCatchIO-transformers\n[2]
  http://docs.yesodweb.com/blog/invertible-monads-exceptions-allocations/\n[3] http://hackage.haskell.org/package/monad-peel\n"
basic-deps:
  stm: ! '>=2.3 && <3'
  base: ! '>=4.5 && <5'
  transformers-base: ! '>=0.4.4 && <0.5'
  transformers: ! '>=0.2 && <0.6'
  transformers-compat: ! '>=0.3 && <0.6'
all-versions:
- '0.1'
- '0.2'
- '0.2.0.1'
- '0.2.0.2'
- '0.2.0.3'
- '0.3'
- '0.3.0.1'
- '0.3.1'
- '0.3.1.1'
- '0.3.1.2'
- '0.3.1.3'
- '0.3.1.4'
- '0.3.2'
- '0.3.2.1'
- '0.3.2.2'
- '0.3.2.3'
- '0.3.3.0'
- '0.3.3.1'
- '1.0.0.0'
- '1.0.0.1'
- '1.0.0.2'
- '1.0.0.3'
{'fraction_non_alphanumeric': 0.10981107402181768, 'fraction_numerical': 0.023779207818576002, 'mean_word_length': 3.1202325251665957, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 65, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 69, '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': '1982356', 'n_tokens_mistral': 10785, 'n_tokens_neox': 10330, 'n_words': 3870}