File: Array.hs

package info (click to toggle)
haskell-monad-memo 0.5.4-3
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 224 kB
  • sloc: haskell: 2,159; makefile: 6
file content (88 lines) | stat: -rw-r--r-- 2,112 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{- |
Module      :  Sample.Memo
Copyright   :  (c) Eduard Sergeev 2013
License     :  BSD-style (see the file LICENSE)

Maintainer  :  eduard.sergeev@gmail.com
Stability   :  experimental
Portability :  non-portable

More advanced examples
-}

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances,
  FlexibleContexts, UndecidableInstances, TypeSynonymInstances #-}

module Example.Customisation.Array
(

  -- * Custom `ArrayMemo`
  -- $UnboxedInt16TupleArray
  Int16Sum,
  evalFibSTUA,
  runFibSTUA,
  evalFibIOUA,
  runFibIOUA

) where

import Data.Ix
import Data.Int
import Data.Array.MArray (MArray, freeze)
import qualified Data.Array.Unboxed as UA
import Control.Monad.ST
import Control.Monad.Writer

import Data.MaybeLike
import Control.Monad.Memo.Class
import Control.Monad.Memo.Array


fibmw 0 = return 0
fibmw 1 = return 1
fibmw n = do
  f1 <- memo fibmw (n-1)
  f2 <- memo fibmw (n-2)
  tell $ Sum 1
  return (f1+f2)

{- $UnboxedInt16TupleArray
The way to memoize a tuple of Int16 values using unboxed `UArrayCache`
-}

-- | A tuple of unboxed `Int16` and `Sum` of it
type Int16Sum = (Int16,Sum Int16)

-- | `MaybeLike` instance for our tuple
instance MaybeLike Int32 Int16Sum where
    nothing = minBound
    isNothing v = v == minBound
    just (a,Sum b) = fromIntegral a * 2^16 + fromIntegral b
    fromJust v =
        let (a,b) = v `divMod` (2^16)
        in (fromIntegral a, Sum (fromIntegral b))

-- | `UArrayMemo` instance for our tuple
-- Now we can use `evalUArrayMemo` and `runUArrayMemo` methods
instance UArrayMemo Int16Sum Int32


evalFibSTUA :: Int -> Int16Sum
evalFibSTUA n = runST $ evalUArrayMemo (runWriterT (fibmw n)) (0,n)

runFibSTUA :: Int -> (Int16Sum, UA.UArray Int Int32)
runFibSTUA n = runST $ do 
   (a,arr) <- runUArrayMemo (runWriterT (fibmw n)) (0,n)
   iarr <- freeze arr
   return (a, iarr)


evalFibIOUA :: Int -> IO Int16Sum
evalFibIOUA n = (`evalUArrayMemo`(0,n)) . runWriterT . fibmw $ n 

runFibIOUA :: Int -> IO (Int16Sum, UA.UArray Int Int32)
runFibIOUA n = do
   (a,arr) <- runUArrayMemo (runWriterT (fibmw n)) (0,n)
   iarr <- freeze arr
   return (a, iarr)