forked from sebfisch/explicit-sharing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlast.hs
60 lines (45 loc) · 1.69 KB
/
last.hs
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
{-# LANGUAGE NoMonomorphismRestriction #-}
-- to compile, run:
-- ghc -rtsopts -O2 --make last
-- $ time ./last 1000000 +RTS -H2000M -K50M
-- True
-- real 0m2.898s
-- user 0m2.050s
-- $ time ./last 10000000 +RTS -H2000M -K50M
-- True
-- real 0m20.585s
-- user 0m19.470s
-- $ time ./last.mcc 1000000 +RTS -h2000m -k50m
-- 1000000
-- real 0m4.895s
-- user 0m3.960s
-- $ time ./last.mcc 10000000 +RTS -h2000m -k50m
-- Not enough free memory after garbage collection
import Control.Monad.Sharing
import Data.Monadic.List
import System ( getArgs )
import Prelude hiding ( last )
main =
do n <- liftM (read.head) getArgs
result <- resultList (last(convert(replicate n True))>>=convert)
mapM_ print (result :: [Bool])
last :: (MonadPlus m, Sharing m) => m (List m Bool) -> m Bool
last l = do x <- share freeBool
l =:= append freeBoolList (cons x nil)
x
append :: Monad m => m (List m a) -> m (List m a) -> m (List m a)
append mxs ys = do xs <- mxs; appendLists xs ys
appendLists :: Monad m => List m a -> m (List m a) -> m (List m a)
appendLists Nil ys = ys
appendLists (Cons x xs) ys = cons x (append xs ys)
freeBool :: MonadPlus m => m Bool
freeBool = return False `mplus` return True
freeBoolList :: MonadPlus m => m (List m Bool)
freeBoolList = nil `mplus` cons freeBool freeBoolList
(=:=) :: MonadPlus m => m (List m Bool) -> m (List m Bool) -> m ()
mxs =:= mys = do xs <- mxs; ys <- mys; eqBoolList xs ys
eqBoolList :: MonadPlus m => List m Bool -> List m Bool -> m ()
eqBoolList Nil Nil = return ()
eqBoolList (Cons x xs) (Cons y ys) = do True <- liftM2 (==) x y
xs =:= ys
eqBoolList _ _ = mzero