Skip to content

Commit

Permalink
Extend documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Bodigrim committed Dec 26, 2023
1 parent 905a30c commit 999f861
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
12 changes: 12 additions & 0 deletions src/Data/Chimera/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ bits = finiteBitSize (0 :: Word)
-- >>> take 10 (toList ch)
-- [0,1,4,9,16,25,36,49,64,81]
--
-- Note that @a@ could be a function type itself,
-- so one can tabulate a function of multiple arguments
-- as a nested 'Chimera' of 'Chimera's.
--
-- @since 0.2.0.0
tabulate :: G.Vector v a => (Word -> a) -> Chimera v a
tabulate f = runIdentity $ tabulateM (coerce f)
Expand Down Expand Up @@ -226,6 +230,11 @@ tabulateM f = Chimera <$> generateArrayM (bits + 1) tabulateSubVector
-- __Note__: Only recursive function calls with decreasing arguments are memoized.
-- If full memoization is desired, use 'tabulateFix'' instead.
--
-- Using unboxed \/ storable \/ primitive vectors with 'tabulateFix' is not always a win:
-- the internal memoizing routine necessarily uses boxed vectors to achieve
-- a certain degree of laziness, so converting to 'UChimera' is extra work.
-- This could pay off in a long run by reducing memory residence though.
--
-- @since 0.2.0.0
tabulateFix :: (G.Vector v a, Typeable v) => ((Word -> a) -> Word -> a) -> Chimera v a
tabulateFix uf = runIdentity $ tabulateFixM (coerce uf)
Expand All @@ -252,6 +261,9 @@ tabulateFix uf = runIdentity $ tabulateFixM (coerce uf)
-- >>> maximumBy (comparing $ memoizeFix collatzF) [0..1000000]
-- 56991483520
--
-- Since 'tabulateFix'' memoizes all recursive calls, even with increasing argument,
-- you most likely do not want to use it with anything else than boxed vectors ('VChimera').
--
-- @since 0.3.2.0
tabulateFix' :: (G.Vector v a, Typeable v) => ((Word -> a) -> Word -> a) -> Chimera v a
tabulateFix' uf = runIdentity $ tabulateFixM' (coerce uf)
Expand Down
22 changes: 16 additions & 6 deletions src/Data/Chimera/Memoize.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,22 @@ import Data.Chimera.Internal
-- would compute @f@ @n@ only once
-- and cache the result in 'VChimera'.
-- This is just a shortcut for 'index' '.' 'tabulate'.
-- When @a@ is 'U.Unbox', it is faster to use
-- 'index' ('tabulate' @f@ :: 'UChimera' @a@).
--
-- prop> memoize f n = f n
--
-- Note that @a@ could be a function type itself. This allows, for instance,
-- to define
--
-- > memoize2 :: (Word -> Word -> a) -> Word -> Word -> a
-- > memoize2 = memoize . (memoize .)
--
-- @since 0.3.0.0
memoize :: (Word -> a) -> (Word -> a)
memoize = index @V.Vector . tabulate

-- | For a given @f@ memoize a recursive function 'fix' @f@,
-- caching results in 'VChimera'.
-- This is just a shortcut for 'index' '.' 'tabulateFix'.
-- When @a@ is 'U.Unbox', it is faster to use
-- 'index' ('tabulateFix' @f@ :: 'UChimera' @a@).
--
-- prop> memoizeFix f n = fix f n
--
Expand All @@ -64,15 +66,23 @@ memoize = index @V.Vector . tabulate
--
-- This function can be used even when arguments
-- of recursive calls are not strictly decreasing,
-- but they might not get memoized. If this is not desired
-- use 'tabulateFix'' instead.
-- but they might not get memoized.
-- For example, here is a routine to measure the length of
-- <https://oeis.org/A006577 Collatz sequence>:
--
-- >>> collatzF f n = if n <= 1 then 0 else 1 + f (if even n then n `quot` 2 else 3 * n + 1)
-- >>> memoizeFix collatzF 27
-- 111
--
-- If you want to memoize all recursive calls, even with increasing arguments,
-- you can employ another function of the same signature:
-- 'Data.Function.fix' '.' ('memoize' '.'). It is less efficient though.
--
-- To memoize recursive functions of multiple arguments, one can use
--
-- > memoizeFix2 :: ((Word -> Word -> a) -> Word -> Word -> a) -> Word -> Word -> a
-- > memoizeFix2 = let memoize2 = memoize . (memoize .) in Data.Function.fix . (memoize2 .)
--
-- @since 0.3.0.0
memoizeFix :: ((Word -> a) -> Word -> a) -> (Word -> a)
memoizeFix = index @V.Vector . tabulateFix

0 comments on commit 999f861

Please sign in to comment.