diff options
author | Vivian McPhail <haskell.vivian.mcphail@gmail.com> | 2010-09-26 21:03:59 +0000 |
---|---|---|
committer | Vivian McPhail <haskell.vivian.mcphail@gmail.com> | 2010-09-26 21:03:59 +0000 |
commit | dbd943b89ff481e0971f86c2271223cfddee7a02 (patch) | |
tree | 71ebd9be93fda53ee5d98986bfaaa1620012533b /examples | |
parent | f2f54ac1d76fc391c0e231b4309ae5c4245cd0f9 (diff) |
add note about strictness
Diffstat (limited to 'examples')
-rw-r--r-- | examples/monadic.hs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/examples/monadic.hs b/examples/monadic.hs new file mode 100644 index 0000000..b933de9 --- /dev/null +++ b/examples/monadic.hs | |||
@@ -0,0 +1,90 @@ | |||
1 | -- monadic computations | ||
2 | -- (contributed by Vivian McPhail) | ||
3 | |||
4 | import Numeric.Container | ||
5 | import Control.Monad.State | ||
6 | import Control.Monad.Maybe | ||
7 | |||
8 | ------------------------------------------- | ||
9 | |||
10 | -- an instance of MonadIO, a monad transformer | ||
11 | type VectorMonadT = StateT Int IO | ||
12 | |||
13 | v :: Vector Int | ||
14 | v = 10 |> [0..] | ||
15 | |||
16 | test1 :: Vector Int -> IO (Vector Int) | ||
17 | test1 = mapVectorM $ \x -> do | ||
18 | putStr $ (show x) ++ " " | ||
19 | return (x + 1) | ||
20 | |||
21 | -- we can have an arbitrary monad AND do IO | ||
22 | addInitialM :: Vector Int -> VectorMonadT () | ||
23 | addInitialM = mapVectorM_ $ \x -> do | ||
24 | i <- get | ||
25 | liftIO $ putStr $ (show $ x + i) ++ " " | ||
26 | put $ x + i | ||
27 | |||
28 | -- sum the values of the even indiced elements | ||
29 | sumEvens :: Vector Int -> Int | ||
30 | sumEvens = foldVectorWithIndex (\x a b -> if x `mod` 2 == 0 then a + b else b) 0 | ||
31 | |||
32 | -- sum and print running total of evens | ||
33 | sumEvensAndPrint :: Vector Int -> VectorMonadT () | ||
34 | sumEvensAndPrint = mapVectorWithIndexM_ $ \ i x -> do | ||
35 | when (i `mod` 2 == 0) $ do | ||
36 | v <- get | ||
37 | put $ v + x | ||
38 | v' <- get | ||
39 | liftIO $ putStr $ (show v') ++ " " | ||
40 | |||
41 | |||
42 | indexPlusSum :: Vector Int -> VectorMonadT () | ||
43 | indexPlusSum v' = do | ||
44 | let f i x = do | ||
45 | s <- get | ||
46 | let inc = x+s | ||
47 | liftIO $ putStr $ show (i,inc) ++ " " | ||
48 | put inc | ||
49 | return inc | ||
50 | v <- mapVectorWithIndexM f v' | ||
51 | liftIO $ do | ||
52 | putStrLn "" | ||
53 | putStrLn $ show v | ||
54 | |||
55 | ------------------------------------------- | ||
56 | |||
57 | -- short circuit | ||
58 | monoStep :: Double -> MaybeT (State Double) () | ||
59 | monoStep d = do | ||
60 | dp <- get | ||
61 | when (d < dp) (fail "negative difference") | ||
62 | put d | ||
63 | {-# INLINE monoStep #-} | ||
64 | |||
65 | isMonotoneIncreasing :: Vector Double -> Bool | ||
66 | isMonotoneIncreasing v = | ||
67 | let res = evalState (runMaybeT $ (mapVectorM_ monoStep v)) (v @> 0) | ||
68 | in case res of | ||
69 | Nothing -> False | ||
70 | Just _ -> True | ||
71 | |||
72 | w = fromList ([1..10]++[10,9..1]) :: Vector Double | ||
73 | |||
74 | ------------------------------------------- | ||
75 | |||
76 | main = do | ||
77 | v' <- test1 v | ||
78 | putStrLn "" | ||
79 | putStrLn $ show v' | ||
80 | evalStateT (addInitialM v) 0 | ||
81 | putStrLn "" | ||
82 | putStrLn $ show (sumEvens v) | ||
83 | evalStateT (sumEvensAndPrint v) 0 | ||
84 | putStrLn "" | ||
85 | evalStateT (indexPlusSum v) 0 | ||
86 | putStrLn "-----------------------" | ||
87 | print $ isMonotoneIncreasing w | ||
88 | print $ isMonotoneIncreasing (subVector 0 7 w) | ||
89 | print $ successive_ (>) v | ||
90 | print $ successive_ (>) w | ||