{-# LANGUAGE LambdaCase #-}
module Data.Function.FastMemo.Util (memoizeFixedLen) where
import Data.Function.FastMemo.Class (Memoizable, memoize)
import GHC.Stack (HasCallStack)
memoizeFixedLen :: (HasCallStack, Memoizable a) => Int -> ([a] -> b) -> [a] -> b
memoizeFixedLen :: forall a b.
(HasCallStack, Memoizable a) =>
Int -> ([a] -> b) -> [a] -> b
memoizeFixedLen Int
n [a] -> b
f
| Int
n forall a. Ord a => a -> a -> Bool
<= Int
0 = forall a b. a -> b -> a
const ([a] -> b
f [])
| Bool
otherwise =
let f' :: a -> [a] -> b
f' = forall a b. Memoizable a => (a -> b) -> a -> b
memoize forall a b. (a -> b) -> a -> b
$ \a
x -> forall a b.
(HasCallStack, Memoizable a) =>
Int -> ([a] -> b) -> [a] -> b
memoizeFixedLen (Int
n forall a. Num a => a -> a -> a
- Int
1) ([a] -> b
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a
x forall a. a -> [a] -> [a]
:))
in \case
[] -> forall a. HasCallStack => [Char] -> a
error [Char]
"List too short"
a
x : [a]
xs -> a -> [a] -> b
f' a
x [a]
xs