<commit_before>homepage: https://github.com/EduardSergeev/monad-memo
changelog-type: text
hash: 311c8465c092dee903e9c67c8a3bf200acc2c379c40ffa52d20f8b0d254d9b33
test-bench-deps:
  test-framework: ! '>=0.3.3'
  base: ! '>=3.0 && <=5.0'
  test-framework-quickcheck2: ! '>=0.2.9'
  criterion: ! '>=0.6'
  array: ! '>=0.3'
  containers: ! '>=0.3'
  transformers: ! '>=0.2'
  random: ! '>=1.0'
  QuickCheck: ! '>=2.0'
  primitive: ! '>=0.3'
  vector: ! '>=0.7'
maintainer: <EMAIL>
synopsis: Memoization monad transformer
changelog: ! '


  0.2.0

  - Added a set of forX functions (for2, for3 and for4) to adapt curried function
  into uncuried MemoCache


  0.3.0

  - Added generalized MemoStateT transformer (to host any Data.MapLike cache-container)

  - MemoT is now MemoStateT instantiated with Data.Map


  0.4.0

  - ArrayCache: mutable array-based MonadCache for top performance

  - VectorCache (and flavours) vector-based MonadCache for even better performance

  - Bug fixes in transformer implementations (Reader, State, RWS)

  - Simple benchmark included

  0.4.1

  - Documentation fixes

  - `Example` is renamed to `example` and is excluded from package''s module hierarchy


  0.5.0

  - Refresh project to be compilable with latest GHC and libraries

  - Remove dependency on `mtl` package (`transformers` is sufficient)

  - Use `Except` instead of depricated `Error`

  - Remove support for `ListT` transformer since it is now depricated

  - Use standard `StateT` & `ReaderT` for `MonadCache` implementations'
basic-deps:
  base: ! '>=3.0 && <=5.0'
  array: ! '>=0.3'
  containers: ! '>=0.3'
  transformers: ! '>=0.2'
  primitive: ! '>=0.3'
  vector: ! '>=0.7'
all-versions:
- '0.1.0'
- '0.1.1'
- '0.2.0'
- '0.3.0'
- '0.4.0'
- '0.4.1'
- '0.5.0'
author: <NAME>
latest: '0.5.0'
description-type: markdown
description: ! "## Purpose\nThis package provides a convenient mechanism for adding
  memoization to Haskell monadic functions.\n\n## Memoization\nMemoization is a well
  known way to speed up function evaluation by caching previously calculated results
  and reusing them whenever a memoized function is needed to be evaluated with the
  same arguments again.\nIt is usually associated with dynamic programming techiques.
  \n\n## Overview\nEven though it is possible to manually add memoization to the code
  which would benefit from it, this ad-hoc approach has usual ad-hoc drawbacks: code
  pollution, bugs, resistance to changes.\nThis package however encapsulates the underlying
  plumbing behind its simple monadic interface `MonadMemo` with a single combinator
  `memo` which, when applied to monadic function, turns it into \"memoized\" one.
  \n\nThe package offers various implementation of `MonadMemo` (which differs in terms
  of performance and requirements) and it is possible to choose/change the implementation
  without affecting the main function code.\nThe range of supported implementations
  \"out of box\" is limited by the range of containers provided by the standard packages
  installed by [Haskel Platform](http://www.haskell.org/platform/):\nfrom default
  pure \"fit them all\" [Data.Map](http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-Map.html)
  to very fast but limiting [vector](http://hackage.haskell.org/packages/archive/vector/latest/doc/html/Data-Vector-Generic-Mutable.html).\nIt
  is also possible to plug-in a custom container (from a third-party library) and
  run existing monadic code with it. \n\nThe default implementation of `MonadMemo`
  is also [monad transformer](http://en.wikibooks.org/wiki/Haskell/Monad_transformers)
  so it can be \"mixed\" with other monads.\nThe package also provides the \"memoized\"
  versions of most standard monads found in [mtl](http://hackage.haskell.org/package/mtl).
  \n\n## Example of usage\n\nA clasic example of function which greatelly benefits
  from memoization is a recursively defined Fibonacci number function.\nA plain version
  of this function can be written in the following way:\n```haskell\nfib :: Integer
  -> Integer\nfib 0 = 0\nfib 1 = 1\nfib n = fib (n-1) + fib (n-2)\n```\nwhich is very
  inefficient (impractical for `n>40`).\n\nWe can rewrite this definition as a monad:\n```haskell\nfibm
  :: Monad m => Integer -> m Integer\nfibm 0 = return 0\nfibm 1 = return 1\nfibm n
  = do\n  f1 <- fibm (n-1)\n  f2 <- fibm (n-2)\n  return (f1+f2)\n```\nand even run
  it with `Identity` monad with identical inefficiency:\n```haskell\nevalFibmId ::
  Integer -> Integer\nevalFibmId = runIdentity . fibm\n```\n\nBut all we need to do
  to make this function \"computable\" for reasonable argument is to add memoization
  for both recursive branches with `memo` combinator:\n```haskell\nfibm :: (MonadMemo
  Integer Integer m) => Integer -> m Integer\nfibm 0 = return 0\nfibm 1 = return 1\nfibm
  n = do\n  f1 <- memo fibm (n-1)\n  f2 <- memo fibm (n-2)\n  return (f1+f2)\n```\nthen,
  to evaluate it with default `Data.Map` based memoization cache we use the following<commit_msg>Update from Hackage at 2018-08-31T06:23:37Z<commit_after>homepage: https://github.com/EduardSergeev/monad-memo
changelog-type: text
hash: 3cb63dcaa9311c813d7aa99c83164cb175e0444622104ac0783c3fee30c034a6
test-bench-deps:
  test-framework: ! '>=0.3.3'
  base: ! '>=3.0 && <=5.0'
  test-framework-quickcheck2: ! '>=0.2.9'
  criterion: ! '>=0.6'
  array: ! '>=0.3'
  containers: ! '>=0.3'
  transformers: ! '>=0.2'
  random: ! '>=1.0'
  QuickCheck: ! '>=2.0'
  primitive: ! '>=0.3'
  vector: ! '>=0.7'
maintainer: <EMAIL>
synopsis: Memoization monad transformer
changelog: ! "\n\n0.2.0\n- Added a set of forX functions (for2, for3 and for4) to
  adapt curried function into uncuried MemoCache\n\n0.3.0\n- Added generalized MemoStateT
  transformer (to host any Data.MapLike cache-container)\n- MemoT is now MemoStateT
  instantiated with Data.Map\n\n0.4.0\n- ArrayCache: mutable array-based MonadCache
  for top performance\n- VectorCache (and flavours) vector-based MonadCache for even
  better performance\n- Bug fixes in transformer implementations (Reader, State, RWS)\n-
  Simple benchmark included\n0.4.1\n- Documentation fixes\n- `Example` is renamed
  to `example` and is excluded from package's module hierarchy\n\n0.5.0\n- Refresh
  project to be compilable with latest GHC and libraries\n- Remove dependency on `mtl`
  package (`transformers` is sufficient)\n- Use `Except` instead of depricated `Error`\n-
  Remove support for `ListT` transformer since it is now depricated\n- Use standard
  `StateT` & `ReaderT` for `MonadCache` implementations\n\n0.5.1\n- Support multiple
  mutable caches in transformers stack\n  This allows Array/Vector-based caches to
  be used for mutually recursive function memoization\n"
basic-deps:
  base: ! '>=3.0 && <=5.0'
  array: ! '>=0.3'
  containers: ! '>=0.3'
  transformers: ! '>=0.2'
  primitive: ! '>=0.3'
  vector: ! '>=0.7'
all-versions:
- '0.1.0'
- '0.1.1'
- '0.2.0'
- '0.3.0'
- '0.4.0'
- '0.4.1'
- '0.5.0'
- '0.5.1'
author: <NAME>
latest: '0.5.1'
description-type: markdown
description: ! "# monad-memo\n[![Build Status](https://travis-ci.org/EduardSergeev/monad-memo.svg?branch=master)](https://travis-ci.org/EduardSergeev/monad-memo)\n\n##
  Purpose\nThis package provides a convenient mechanism for adding memoization to
  Haskell monadic functions.\n\n## Memoization\nMemoization is a well known way to
  speed up function evaluation by caching previously calculated results and reusing
  them whenever a memoized function is needed to be evaluated with the same arguments
  again.\nIt is usually associated with dynamic programming techiques. \n\n## Overview\nEven
  though it is possible to manually add memoization to the code which would benefit
  from it, this ad-hoc approach has usual ad-hoc drawbacks: code pollution, bugs,
  resistance to changes.\nThis package however encapsulates the underlying plumbing
  behind its simple monadic interface `MonadMemo` with a single combinator `memo`
  which, when applied to monadic function, turns it into \"memoized\" one. \n\nThe
  package offers various implementation of `MonadMemo` (which differs in terms of
  performance and requirements) and it is possible to choose/change the implementation
  without affecting the main function code.\nThe range of supported implementations
  \"out of box\" is limited by the range of containers provided by the standard packages
  installed by [Haskel Platform](http://www.haskell.org/platform/):\nfrom default
  pure \"fit them all\" [Data.Map](http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-Map.html)
  to very fast but limiting [vector](http://hackage.haskell.org/packages/archive/vector/latest/doc/html/Data-Vector-Generic-Mutable.html).\nIt
  is also possible to plug-in a custom container (from a third-party library) and
  run existing monadic code with it. \n\nThe default implementation of `MonadMemo`
  is also [monad transformer](http://en.wikibooks.org/wiki/Haskell/Monad_transformers)
  so it can be \"mixed\" with other monads.\nThe package also provides the \"memoized\"
  versions of most standard monads found in [mtl](http://hackage.haskell.org/package/mtl).
  \n\n## Example of usage\n\nA clasic example of function which greatelly benefits
  from memoization is a recursively defined Fibonacci number function.\nA plain version
  of this function can be written in the following way:\n```haskell\nfib :: Integer
  -> Integer\nfib 0 = 0\nfib 1 = 1\nfib n = fib (n-1) + fib (n-2)\n```\nwhich is very
  inefficient (impractical for `n>40`).\n\nWe can rewrite this definition as a monad:\n```haskell\nfibm
  :: Monad m => Integer -> m Integer\nfibm 0 = return 0\nfibm 1 = return 1\nfibm n
  = do\n  f1 <- fibm (n-1)\n  f2 <- fibm (n-2)\n  return (f1+f2)\n```\nand even run
  it with `Identity` monad with identical inefficiency:\n```haskell\nevalFibmId ::
  Integer -> Integer\nevalFibmId = runIdentity . fibm\n```\n\nBut all we need to do
  to make this function \"computable\" for reasonable argument is to add memoization
  for both recursive branches with `memo` combinator:\n```haskell\nfibm :: (MonadMemo
  Integer Integer m) => Integer -> m Integer\nfibm 0 = return 0\nfibm 1 = return 1\nfibm
  n = do\n  f1 <- memo fibm (n-1)\n  f2 <- memo fibm (n-2)\n  return (f1+f2)\n```\nthen,
  to evaluate it with default `Data.Map` based memoization cache we use the following
{'fraction_non_alphanumeric': 0.11910717721762555, 'fraction_numerical': 0.03107562055031749, 'mean_word_length': 3.9033018867924527, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 55, 'https://': 4, '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': '5802598', 'n_tokens_mistral': 3688, 'n_tokens_neox': 3457, 'n_words': 1147}