{-|
Module      : Advent.Memo
Description : Memoization functions
Copyright   : (c) Eric Mertens, 2021
License     : ISC
Maintainer  : emertens@gmail.com

Re-exported MemoTrie operations and extended
arity memoization.

-}
module Advent.Memo (
  HasTrie,
  memo, memo2, memo3, memo4, memo5, memo6,
  ) where

import Data.MemoTrie (HasTrie, memo, memo2, memo3, mup)

-- | Memoize a quaternary function on successive arguments.
-- Take care to exploit any partial evaluation.
memo4 ::
  (HasTrie a, HasTrie b, HasTrie c, HasTrie d) =>
  (a -> b -> c -> d -> e) ->
  (a -> b -> c -> d -> e)
memo4 :: forall a b c d e.
(HasTrie a, HasTrie b, HasTrie c, HasTrie d) =>
(a -> b -> c -> d -> e) -> a -> b -> c -> d -> e
memo4 = ((b -> c -> d -> e) -> b -> c -> d -> e)
-> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> e
forall t b c. HasTrie t => (b -> c) -> (t -> b) -> t -> c
mup (b -> c -> d -> e) -> b -> c -> d -> e
forall r s t a.
(HasTrie r, HasTrie s, HasTrie t) =>
(r -> s -> t -> a) -> r -> s -> t -> a
memo3

-- | Memoize a quaternary function on successive arguments.
-- Take care to exploit any partial evaluation.
memo5 ::
  (HasTrie a, HasTrie b, HasTrie c, HasTrie d, HasTrie e) =>
  (a -> b -> c -> d -> e -> f) ->
  (a -> b -> c -> d -> e -> f)
memo5 :: forall a b c d e f.
(HasTrie a, HasTrie b, HasTrie c, HasTrie d, HasTrie e) =>
(a -> b -> c -> d -> e -> f) -> a -> b -> c -> d -> e -> f
memo5 = ((b -> c -> d -> e -> f) -> b -> c -> d -> e -> f)
-> (a -> b -> c -> d -> e -> f) -> a -> b -> c -> d -> e -> f
forall t b c. HasTrie t => (b -> c) -> (t -> b) -> t -> c
mup (b -> c -> d -> e -> f) -> b -> c -> d -> e -> f
forall a b c d e.
(HasTrie a, HasTrie b, HasTrie c, HasTrie d) =>
(a -> b -> c -> d -> e) -> a -> b -> c -> d -> e
memo4

-- | Memoize a quaternary function on successive arguments.
-- Take care to exploit any partial evaluation.
memo6 ::
  (HasTrie a, HasTrie b, HasTrie c, HasTrie d, HasTrie e, HasTrie f) =>
  (a -> b -> c -> d -> e -> f -> g) ->
  (a -> b -> c -> d -> e -> f -> g)
memo6 :: forall a b c d e f g.
(HasTrie a, HasTrie b, HasTrie c, HasTrie d, HasTrie e,
 HasTrie f) =>
(a -> b -> c -> d -> e -> f -> g)
-> a -> b -> c -> d -> e -> f -> g
memo6 = ((b -> c -> d -> e -> f -> g) -> b -> c -> d -> e -> f -> g)
-> (a -> b -> c -> d -> e -> f -> g)
-> a
-> b
-> c
-> d
-> e
-> f
-> g
forall t b c. HasTrie t => (b -> c) -> (t -> b) -> t -> c
mup (b -> c -> d -> e -> f -> g) -> b -> c -> d -> e -> f -> g
forall a b c d e f.
(HasTrie a, HasTrie b, HasTrie c, HasTrie d, HasTrie e) =>
(a -> b -> c -> d -> e -> f) -> a -> b -> c -> d -> e -> f
memo5