diff options
Diffstat (limited to 'testsuite/tests/programs/andre_monad')
-rw-r--r-- | testsuite/tests/programs/andre_monad/Main.hs | 89 | ||||
-rw-r--r-- | testsuite/tests/programs/andre_monad/Makefile | 3 | ||||
-rw-r--r-- | testsuite/tests/programs/andre_monad/andre_monad.stdout | 1 | ||||
-rw-r--r-- | testsuite/tests/programs/andre_monad/test.T | 8 |
4 files changed, 101 insertions, 0 deletions
diff --git a/testsuite/tests/programs/andre_monad/Main.hs b/testsuite/tests/programs/andre_monad/Main.hs new file mode 100644 index 0000000000..7e3dda6362 --- /dev/null +++ b/testsuite/tests/programs/andre_monad/Main.hs @@ -0,0 +1,89 @@ +-- Evaluator in a monad: with execution counts +-- Phil Wadler, 11 October 1991 + +-- Types are optional. Some must be commented out to +-- work around a bug in Gofer. + +-- The count monad + +type M a = (a, Int) + +unit :: a -> M a +unit a = (a, 0) + +bind :: M a -> (a -> M b) -> M b +m `bind` k = case m of + (a,i) -> case k a of + (b,j) -> (b,i+j) + +-- disp :: Text a => M a -> String +disp (a,i) = show a ++ "\nCount: " ++ show i + +tick :: M () +tick = ((), 1) + +-- The evaluator +-- Lines with * are only change from evalIdent + +data Op = Add | Sub | Mul | Quo +data Term = Con Int | Bin Op Term Term + +eval :: Term -> M Int +eval (Con i) = unit i +eval (Bin op u v) = eval u `bind` (\a -> + eval v `bind` (\b -> + go op a b `bind` (\c -> -- * + tick `bind` (\ () -> -- * + unit c)))) -- * + +go :: Op -> Int -> Int -> M Int +go Add a b = unit (a+b) +go Sub a b = unit (a-b) +go Mul a b = unit (a*b) +go Quo a b = unit (a `quot` b) -- WDP: was "div" + +test :: Term -> String +test t = disp (eval t) + +-- Test data + +add, sub, mul, quo :: Term -> Term -> Term +u `add` v = Bin Add u v +u `sub` v = Bin Sub u v +u `mul` v = Bin Mul u v +u `quo` v = Bin Quo u v + +term0,term1,term2 :: Term +term0 = Con 6 `mul` Con 9 +term1 = (Con 4 `mul` Con 13) `add` Con 2 +term2 = (Con 1 `quo` Con 2) `add` Con 2 +term3 = (((((((((((((((((((((((((((((((( + (((((((((((((((((((((((((((((( + Con 7777 `mul` Con 13) `quo` Con 13) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + `mul` Con 755) `quo` Con 755) `mul` Con 333) + `quo` Con 755) `mul` Con 755) `mul` Con 333) + +sb 0 = term2 +sb n = if (n `mod` 2) == 0 + then term2 `add` (sb (n-1)) + else term2 `sub` (sb (n-1)) + +main = print (show (eval (sb 5000))) diff --git a/testsuite/tests/programs/andre_monad/Makefile b/testsuite/tests/programs/andre_monad/Makefile new file mode 100644 index 0000000000..9101fbd40a --- /dev/null +++ b/testsuite/tests/programs/andre_monad/Makefile @@ -0,0 +1,3 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk diff --git a/testsuite/tests/programs/andre_monad/andre_monad.stdout b/testsuite/tests/programs/andre_monad/andre_monad.stdout new file mode 100644 index 0000000000..7ea358a0c9 --- /dev/null +++ b/testsuite/tests/programs/andre_monad/andre_monad.stdout @@ -0,0 +1 @@ +"(2,15002)" diff --git a/testsuite/tests/programs/andre_monad/test.T b/testsuite/tests/programs/andre_monad/test.T new file mode 100644 index 0000000000..e5ad78feda --- /dev/null +++ b/testsuite/tests/programs/andre_monad/test.T @@ -0,0 +1,8 @@ +# exhausts Hugs's heap (CAF leak) +test('andre_monad', + [skip_if_fast, + extra_clean(['Main.hi', 'Main.o']), + omit_compiler_types(['hugs'])], + multimod_compile_and_run, + ['Main', '']) + |