-- | Implicit sharing
module Main where
import Data.Monoid
import Control.Applicative hiding (Const)
import Data.Fix
import Data.Fix.Cse
import Exp
-----------------------------------------------
-- implicit sharing
newtype T = T { unT :: Fix Exp }
deriving (Show, Eq)
instance Num T where
(+) a b = T $ Fix $ Add (unT a) (unT b)
fromInteger = T . Fix . Const . fromInteger
(*) = undefined
negate = undefined
abs = undefined
signum = undefined
var :: String -> T
var = T . Fix . Var
x = var "x"
y = var "y"
z = var "z"
mulT :: Int -> T -> T
mulT 0 _ = 0
mulT 1 x = x
mulT n x
| n `mod` 2 == 0 = mulT (n `div` 2) (x + x)
| otherwise = mulT (n - 1) x + x
-- interpreters
asInt :: T -> Int
asInt = cata expAsInt . unT
asDepth :: T -> Int
asDepth = cata expAsDepth . unT
exec :: T -> Dag Exp
exec = cse . unT
-----------------------------------------------
-- expression
expr = mulT (2^20) 2
main = do
putStrLn $ show $ length $ fromDag $ exec expr