{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnicodeSyntax #-}
{-# LANGUAGE TypeApplications #-}
module Data.Enum.Memo
(
memoize
, memoize2
, memoize3
, memoize4
, memoize5
) where
import Prelude hiding (lookup)
import Data.Array ((!), array)
memoize :: ∀ k v. (Bounded k, Enum k) => (k -> v) -> k -> v
memoize :: forall k v. (Bounded k, Enum k) => (k -> v) -> k -> v
memoize k -> v
f = case forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array (Int, Int)
bounds [(Int, v)]
vals of
Array Int v
memo -> \k
k -> Array Int v
memo forall i e. Ix i => Array i e -> i -> e
! forall a. Enum a => a -> Int
fromEnum k
k
where
bounds :: (Int, Int)
bounds = (forall a. Enum a => a -> Int
fromEnum @k forall a. Bounded a => a
minBound, forall a. Enum a => a -> Int
fromEnum @k forall a. Bounded a => a
maxBound)
vals :: [(Int, v)]
vals = [(forall a. Enum a => a -> Int
fromEnum k
k, k -> v
f k
k) | k
k <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]]
memoize2 :: ∀ k1 k2 v.
( Bounded k1, Enum k1
, Bounded k2, Enum k2
)
=> (k1 -> k2 -> v) -> k1 -> k2 -> v
memoize2 :: forall k1 k2 v.
(Bounded k1, Enum k1, Bounded k2, Enum k2) =>
(k1 -> k2 -> v) -> k1 -> k2 -> v
memoize2 k1 -> k2 -> v
f = case forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array ((Int, Int), (Int, Int))
bounds [((Int, Int), v)]
vals of
Array (Int, Int) v
memo -> \k1
k1 k2
k2 -> Array (Int, Int) v
memo forall i e. Ix i => Array i e -> i -> e
!
( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
)
where
bounds :: ((Int, Int), (Int, Int))
bounds = ( ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
minBound
)
, ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
maxBound
)
)
vals :: [((Int, Int), v)]
vals = [( ( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
)
, k1 -> k2 -> v
f k1
k1 k2
k2
) | k1
k1 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k2
k2 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]]
memoize3 :: ∀ k1 k2 k3 v.
( Bounded k1, Enum k1
, Bounded k2, Enum k2
, Bounded k3, Enum k3
)
=> (k1 -> k2 -> k3 -> v) -> k1 -> k2 -> k3 -> v
memoize3 :: forall k1 k2 k3 v.
(Bounded k1, Enum k1, Bounded k2, Enum k2, Bounded k3, Enum k3) =>
(k1 -> k2 -> k3 -> v) -> k1 -> k2 -> k3 -> v
memoize3 k1 -> k2 -> k3 -> v
f = case forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array ((Int, Int, Int), (Int, Int, Int))
bounds [((Int, Int, Int), v)]
vals of
Array (Int, Int, Int) v
memo -> \k1
k1 k2
k2 k3
k3 -> Array (Int, Int, Int) v
memo forall i e. Ix i => Array i e -> i -> e
!
( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
)
where
bounds :: ((Int, Int, Int), (Int, Int, Int))
bounds = ( ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
minBound
)
, ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
maxBound
)
)
vals :: [((Int, Int, Int), v)]
vals = [( ( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
)
, k1 -> k2 -> k3 -> v
f k1
k1 k2
k2 k3
k3
) | k1
k1 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k2
k2 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k3
k3 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]]
memoize4 :: ∀ k1 k2 k3 k4 v.
( Bounded k1, Enum k1
, Bounded k2, Enum k2
, Bounded k3, Enum k3
, Bounded k4, Enum k4
)
=> (k1 -> k2 -> k3 -> k4 -> v) -> k1 -> k2 -> k3 -> k4 -> v
memoize4 :: forall k1 k2 k3 k4 v.
(Bounded k1, Enum k1, Bounded k2, Enum k2, Bounded k3, Enum k3,
Bounded k4, Enum k4) =>
(k1 -> k2 -> k3 -> k4 -> v) -> k1 -> k2 -> k3 -> k4 -> v
memoize4 k1 -> k2 -> k3 -> k4 -> v
f = case forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array ((Int, Int, Int, Int), (Int, Int, Int, Int))
bounds [((Int, Int, Int, Int), v)]
vals of
Array (Int, Int, Int, Int) v
memo -> \k1
k1 k2
k2 k3
k3 k4
k4 -> Array (Int, Int, Int, Int) v
memo forall i e. Ix i => Array i e -> i -> e
!
( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
, forall a. Enum a => a -> Int
fromEnum k4
k4
)
where
bounds :: ((Int, Int, Int, Int), (Int, Int, Int, Int))
bounds = ( ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k4 forall a. Bounded a => a
minBound
)
, ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k4 forall a. Bounded a => a
maxBound
)
)
vals :: [((Int, Int, Int, Int), v)]
vals = [( ( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
, forall a. Enum a => a -> Int
fromEnum k4
k4
)
, k1 -> k2 -> k3 -> k4 -> v
f k1
k1 k2
k2 k3
k3 k4
k4
) | k1
k1 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k2
k2 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k3
k3 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k4
k4 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]]
memoize5 :: ∀ k1 k2 k3 k4 k5 v.
( Bounded k1, Enum k1
, Bounded k2, Enum k2
, Bounded k3, Enum k3
, Bounded k4, Enum k4
, Bounded k5, Enum k5
)
=> (k1 -> k2 -> k3 -> k4 -> k5 -> v) -> k1 -> k2 -> k3 -> k4 -> k5 -> v
memoize5 :: forall k1 k2 k3 k4 k5 v.
(Bounded k1, Enum k1, Bounded k2, Enum k2, Bounded k3, Enum k3,
Bounded k4, Enum k4, Bounded k5, Enum k5) =>
(k1 -> k2 -> k3 -> k4 -> k5 -> v)
-> k1 -> k2 -> k3 -> k4 -> k5 -> v
memoize5 k1 -> k2 -> k3 -> k4 -> k5 -> v
f = case forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
array ((Int, Int, Int, Int, Int), (Int, Int, Int, Int, Int))
bounds [((Int, Int, Int, Int, Int), v)]
vals of
Array (Int, Int, Int, Int, Int) v
memo -> \k1
k1 k2
k2 k3
k3 k4
k4 k5
k5 -> Array (Int, Int, Int, Int, Int) v
memo forall i e. Ix i => Array i e -> i -> e
!
( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
, forall a. Enum a => a -> Int
fromEnum k4
k4
, forall a. Enum a => a -> Int
fromEnum k5
k5
)
where
bounds :: ((Int, Int, Int, Int, Int), (Int, Int, Int, Int, Int))
bounds = ( ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k4 forall a. Bounded a => a
minBound
, forall a. Enum a => a -> Int
fromEnum @k5 forall a. Bounded a => a
minBound
)
, ( forall a. Enum a => a -> Int
fromEnum @k1 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k2 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k3 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k4 forall a. Bounded a => a
maxBound
, forall a. Enum a => a -> Int
fromEnum @k5 forall a. Bounded a => a
maxBound
)
)
vals :: [((Int, Int, Int, Int, Int), v)]
vals = [( ( forall a. Enum a => a -> Int
fromEnum k1
k1
, forall a. Enum a => a -> Int
fromEnum k2
k2
, forall a. Enum a => a -> Int
fromEnum k3
k3
, forall a. Enum a => a -> Int
fromEnum k4
k4
, forall a. Enum a => a -> Int
fromEnum k5
k5
)
, k1 -> k2 -> k3 -> k4 -> k5 -> v
f k1
k1 k2
k2 k3
k3 k4
k4 k5
k5
) | k1
k1 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k2
k2 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k3
k3 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k4
k4 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]
, k5
k5 <- [forall a. Bounded a => a
minBound..forall a. Bounded a => a
maxBound]]