[Haskell-ELTE] alapveto memoisation Haskellben
Divianszky Peter
divip at aszt.inf.elte.hu
Fri Mar 27 20:57:32 CET 2009
Sziasztok!
Az alabbi modul roviden bevezet a Haskell memoisation-be, abba a fajtaba,
amit alapbol tud a Haskell: a *nem ad-hoc polimorf* konstansokat
megjegyzi.
Azok az esetek az erdekesek, amikor ezek a konstansok lokalisak.
Udv,
Peti
----------------------------------------
-------------- Zero memoisation
choose :: Int -> Int -> Integer
choose n m = pascalTriangle !! n !! min m (n-m) where
pascalTriangle :: [[Integer]]
pascalTriangle = iterate next [1]
{-
(choose 1500 500, choose 1500 500)
-- computes 1500+1500 Pascal triangle lines
-}
-------------- Total memoisation
chooseMemo :: Int -> Int -> Integer
chooseMemo n m = pascalTriangle !! n !! min m (n-m)
pascalTriangle :: [[Integer]]
pascalTriangle = iterate next [1]
{-
(chooseMemo 1500 500, chooseMemo 1500 500)
-- computes 1500+0 Pascal triangle lines (if chooseMemo was not called
yet)
-}
-------------- 1000 line memoisation
chooseMemo1000 :: Int -> Int -> Integer
chooseMemo1000 n m = pascalTriangle !! n !! min m (n-m) where
pascalTriangle :: [[Integer]]
pascalTriangle = continue next (take 1000 pascalTriangle')
-- private for chooseMemo1000
pascalTriangle' :: [[Integer]]
pascalTriangle' = iterate next [1]
{-
(chooseMemo1000 1500 500, chooseMemo1000 1500 500)
-- computes 1000+500 + 0+500 Pascal triangle lines (if chooseMemo1000
was not called yet)
-}
-------------- Adjustable memoisation
chooseMemoN :: Int -> (Int -> Int -> Integer)
chooseMemoN i = choose where
choose :: Int -> Int -> Integer
choose n m = pascalTriangle !! n !! min m (n-m) where
pascalTriangle :: [[Integer]]
pascalTriangle = continue next (take i pascalTriangle')
pascalTriangle' :: [[Integer]]
pascalTriangle' = iterate next [1]
{-
let f = chooseMemoN 1000 in (f 1500 500, f 1500 500)
-- computes 1000+ 500+500 Pascal triangle lines
(chooseMemoN 1000 1500 500, chooseMemoN 2000 1500 500)
-- computes 1000+500 + 1500+0 Pascal triangle lines
-}
-------------- Adjustable memoisation with sharing
chooseMemoMemoN :: Int -> (Int -> Int -> Integer)
chooseMemoMemoN i = choose where
choose :: Int -> Int -> Integer
choose n m = pascalTriangle !! n !! min m (n-m) where
pascalTriangle :: [[Integer]]
pascalTriangle = continue next (take i pascalTriangle'')
pascalTriangle'' :: [[Integer]]
pascalTriangle'' = iterate next [1]
{-
let f = chooseMemoMemoN 1000 in (f 1500 500, f 1500 500)
-- computes 1000+ 500+500 Pascal triangle lines (if chooseMemoMemoN was
not called yet)
(chooseMemoMemoN 1000 1500 500, chooseMemoMemoN 2000 1500 500)
-- computes 1000+500 + 500+0 Pascal triangle lines (if chooseMemoMemoN
was not called yet)
(chooseMemoMemoN 2000 1500 500, chooseMemoMemoN 1000 1500 500)
-- computes 1500+0 + 0+500 Pascal triangle lines (if chooseMemoMemoN
was not called yet)
-}
--------------- Alternate solution for chooseMemoMemoN
chooseMemoMemoN' :: Int -> (Int -> Int -> Integer)
chooseMemoMemoN' i = choose where
choose :: Int -> Int -> Integer
choose n m = pascalTriangleMemoN i !! n !! min m (n-m) where
pascalTriangleMemoN :: Int -> [[Integer]]
pascalTriangleMemoN = iterateMemoN next [1]
--------------- Helper functions
next :: [Integer] -> [Integer]
next l = [1] ++ zipWith (+) l (tail l) ++ [1]
-- | Continue iteration
continue :: (a -> a) -> [a] -> [a]
continue f [x] = iterate f x
continue f (x:xs) = x: continue f xs
-- | Same as iterate but memoise first n value
iterateMemoN :: (a -> a) -> a -> (Int -> [a])
iterateMemoN f x = \n -> continue f (take n xs) where
xs = iterate f x
More information about the Haskell
mailing list