-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Memoization combinators using arrays for finite sub-domains of functions
--   
--   Memoization combinators are great for providing high-performance
--   Haskell programs, but they can be even faster if memoization is
--   performed on a finite, discrete domain since an array can then be used
--   to store results.
--   
--   This package provides various combinators for doing just this,
--   including also combinators for quanitzing and discretizing
--   Float/Double-valued functions.
--   
--   Example:
--   
--   <pre>
--   fib' :: (Int -&gt; Int) -&gt; Int -&gt; Int
--   fib' _ 0 = 1
--   fib' _ 1 = 1
--   fib' rec n = rec (n - 1) + rec (n - 2)
--   fib :: Int -&gt; Int
--   fib = arrayMemoFix (0, 1000) fib'
--   </pre>
@package array-memoize
@version 0.6.0

module Data.Function.ArrayMemoize

-- | Memoize a function over a finite (sub)domain, using an array (boxed),
--   e.g., <tt> arrayMemo (0, 20) f </tt> memoizes f between from 0 to 20.
arrayMemo :: (Ix a, ArrayMemoizable b) => (a, a) -> (a -> b) -> (a -> b)

-- | Memoize a fixed point of a function over a sub domain. Similar to
--   <tt>fix</tt>, but over <a>arrayMemo</a>, passing a function a memoized
--   version of itself.
arrayMemoFix :: (Ix a, ArrayMemoizable b) => (a, a) -> ((a -> b) -> (a -> b)) -> a -> b

-- | Memoize a mutual fixed point for two functions (over sub domains of
--   these functions).
arrayMemoFixMutual :: (ArrayMemoizable b, ArrayMemoizable d, Ix a, Ix c) => (a, a) -> (c, c) -> ((a -> b) -> (c -> d) -> (a -> b)) -> ((a -> b) -> (c -> d) -> (c -> d)) -> (a -> b)

-- | Memoize a mutual fixed point for three functions (over sub domains of
--   these functions).
arrayMemoFixMutual3 :: (ArrayMemoizable b, ArrayMemoizable d, ArrayMemoizable f, Ix a, Ix c, Ix e) => (a, a) -> (c, c) -> (e, e) -> ((a -> b) -> (c -> d) -> (e -> f) -> (a -> b)) -> ((a -> b) -> (c -> d) -> (e -> f) -> (c -> d)) -> ((a -> b) -> (c -> d) -> (e -> f) -> (e -> f)) -> (a -> b)

-- | Memoize a function over a finite (sub)domain, using an unboxed
--   <a>IO</a> array. This requires the incoming function to return results
--   in the <a>IO</a> monad, but should preferable be pure.
uarrayMemoFixIO :: (Ix a, UArrayMemoizable b) => (a, a) -> ((a -> IO b) -> (a -> IO b)) -> a -> IO b

-- | Memoize and discretize a function over a finite (sub)domain, using an
--   array. e.g. <tt> discretemMemo (0.0, 10.0) 2.0 f </tt> returns a
--   discretized version of f (with the discrete type defined by
--   <a>Discrete</a>) in the range 0.0 to 10.0 with step size 2.0 (i.e.,
--   the resulting discrete domain is of size 5).
discreteMemo :: (ArrayMemoizable b, Discretize a) => (a, a) -> a -> (a -> b) -> (Discrete a -> b)

-- | Memoize and discretize a fixed point of a function over a subdomain
--   with discretization step
discreteMemoFix :: (ArrayMemoizable b, Discretize a) => (a, a) -> a -> ((a -> b) -> (a -> b)) -> (Discrete a -> b)

-- | Memoize and quantize a function over a finite (sub)domain, using a
--   boxed array, e.g, <tt> quantizedMemo (0.0, 10.0) 2.0 f </tt> memoizes
--   f between 0.0 and 10.0 with step size 2.0 (i.e. the function is
--   quantized into 5 parts, memoized into an array of size 5).
quantizedMemo :: (ArrayMemoizable b, Discretize a) => (a, a) -> a -> (a -> b) -> (a -> b)

-- | Memoize and quantize a fixed point of a function. Similar to
--   <tt>fix</tt>, but using <a>quantizedMemo</a> to pass the fixed
--   function a quantized memoized version of itself, therefore memoizing
--   any recursive calls.
quantizedMemoFix :: (ArrayMemoizable b, Discretize a) => (a, a) -> a -> ((a -> b) -> (a -> b)) -> (a -> b)

-- | Memoize and quantize a mutually recursive fixed point of two
--   functions.
quantizedMemoFixMutual :: (ArrayMemoizable b, ArrayMemoizable d, Discretize a, Discretize c) => (a, a) -> a -> (c, c) -> c -> ((a -> b) -> (c -> d) -> (a -> b)) -> ((a -> b) -> (c -> d) -> (c -> d)) -> (a -> b)

-- | Memoize and quantize a mutually recursive fixed point of three
--   functions.
quantizedMemoFixMutual3 :: (ArrayMemoizable b, ArrayMemoizable d, ArrayMemoizable f, Discretize a, Discretize c, Discretize e) => (a, a) -> a -> (c, c) -> c -> (e, e) -> e -> ((a -> b) -> (c -> d) -> (e -> f) -> (a -> b)) -> ((a -> b) -> (c -> d) -> (e -> f) -> (c -> d)) -> ((a -> b) -> (c -> d) -> (e -> f) -> (e -> f)) -> (a -> b)

-- | <a>ArrayMemoizable</a> defines the subset of types for which we can do
--   array memoization
class ArrayMemoizable a
newArray_ :: (ArrayMemoizable a, Ix i) => (i, i) -> ST s (STArray s i a)
writeArray :: (ArrayMemoizable a, Ix i) => STArray s i a -> i -> a -> ST s ()

-- | <a>UArrayMemoizable</a> defines the subset of types for which we can
--   do unboxed IOUArray memoization
class IArray UArray a => UArrayMemoizable a
newUArray_ :: (UArrayMemoizable a, Ix i) => (i, i) -> IO (IOUArray i a)
writeUArray :: (UArrayMemoizable a, Ix i) => IOUArray i a -> i -> a -> IO ()
readUArray :: (UArrayMemoizable a, Ix i) => IOUArray i a -> i -> IO a

-- | Discretization of float/double values and tuples
class (Ix (Discrete t), Enum (Discrete t)) => Discretize t where type Discrete t where {
    type family Discrete t;
}
discretize :: Discretize t => t -> t -> Discrete t
continuize :: Discretize t => t -> Discrete t -> t

-- | Discretized a function function. The second parameter is the
--   discretisation step.
discrete :: Discretize a => (a -> b) -> a -> (Discrete a -> b)
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Types.Float
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Types.Double
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Integer.Type.Integer
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Types.Int
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Types.Bool
instance Data.Function.ArrayMemoize.ArrayMemoizable GHC.Types.Char
instance Data.Function.ArrayMemoize.UArrayMemoizable GHC.Types.Float
instance Data.Function.ArrayMemoize.UArrayMemoizable GHC.Types.Double
instance Data.Function.ArrayMemoize.UArrayMemoizable GHC.Types.Int
instance Data.Function.ArrayMemoize.UArrayMemoizable GHC.Types.Char
instance (GHC.Enum.Enum a, GHC.Enum.Enum b) => GHC.Enum.Enum (a, b)
instance (GHC.Enum.Enum a, GHC.Enum.Enum b, GHC.Enum.Enum c) => GHC.Enum.Enum (a, b, c)
instance (GHC.Num.Num a, GHC.Num.Num b) => GHC.Num.Num (a, b)
instance (GHC.Num.Num a, GHC.Num.Num b, GHC.Num.Num c) => GHC.Num.Num (a, b, c)
instance Data.Function.ArrayMemoize.Discretize GHC.Types.Float
instance Data.Function.ArrayMemoize.Discretize GHC.Types.Double
instance (Data.Function.ArrayMemoize.Discretize a, Data.Function.ArrayMemoize.Discretize b) => Data.Function.ArrayMemoize.Discretize (a, b)
instance (Data.Function.ArrayMemoize.Discretize a, Data.Function.ArrayMemoize.Discretize b, Data.Function.ArrayMemoize.Discretize c) => Data.Function.ArrayMemoize.Discretize (a, b, c)
