diff options
author | Vivian McPhail <haskell.vivian.mcphail@gmail.com> | 2010-09-26 09:38:35 +0000 |
---|---|---|
committer | Vivian McPhail <haskell.vivian.mcphail@gmail.com> | 2010-09-26 09:38:35 +0000 |
commit | 632c2c5a8b934fd8b54c8be68d178aa49323077d (patch) | |
tree | d926d5a4b651f138d1f2ac4f7805d382839a6364 /lib/Data/Packed | |
parent | 67ee05c858926358fcbe8b9944b43aba6b94d4de (diff) |
add successive
Diffstat (limited to 'lib/Data/Packed')
-rw-r--r-- | lib/Data/Packed/Vector.hs | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/lib/Data/Packed/Vector.hs b/lib/Data/Packed/Vector.hs index eaf4b9c..23fe37f 100644 --- a/lib/Data/Packed/Vector.hs +++ b/lib/Data/Packed/Vector.hs | |||
@@ -22,7 +22,8 @@ module Data.Packed.Vector ( | |||
22 | subVector, takesV, join, | 22 | subVector, takesV, join, |
23 | mapVector, zipVector, zipVectorWith, unzipVector, unzipVectorWith, | 23 | mapVector, zipVector, zipVectorWith, unzipVector, unzipVectorWith, |
24 | mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, | 24 | mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, |
25 | foldLoop, foldVector, foldVectorG, foldVectorWithIndex | 25 | foldLoop, foldVector, foldVectorG, foldVectorWithIndex, |
26 | successive_, successive | ||
26 | ) where | 27 | ) where |
27 | 28 | ||
28 | import Data.Packed.Internal.Vector | 29 | import Data.Packed.Internal.Vector |
@@ -82,4 +83,54 @@ zipVector = zipVectorWith (,) | |||
82 | unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b) | 83 | unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vector a,Vector b) |
83 | unzipVector = unzipVectorWith id | 84 | unzipVector = unzipVectorWith id |
84 | 85 | ||
86 | ------------------------------------------------------------------- | ||
87 | |||
88 | newtype State s a = State { runState :: s -> (a,s) } | ||
89 | |||
90 | instance Monad (State s) where | ||
91 | return a = State $ \s -> (a,s) | ||
92 | m >>= f = State $ \s -> let (a,s') = runState m s | ||
93 | in runState (f a) s' | ||
94 | |||
95 | state_get :: State s s | ||
96 | state_get = State $ \s -> (s,s) | ||
97 | |||
98 | state_put :: s -> State s () | ||
99 | state_put s = State $ \_ -> ((),s) | ||
100 | |||
101 | evalState :: State s a -> s -> a | ||
102 | evalState m s = fst $ runState m s | ||
103 | |||
104 | newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } | ||
105 | |||
106 | instance Monad m => Monad (MaybeT m) where | ||
107 | return a = MaybeT $ return $ Just a | ||
108 | m >>= f = MaybeT $ do | ||
109 | res <- runMaybeT m | ||
110 | case res of | ||
111 | Nothing -> return Nothing | ||
112 | Just r -> runMaybeT (f r) | ||
113 | fail _ = MaybeT $ return Nothing | ||
114 | |||
115 | lift_maybe m = MaybeT $ do | ||
116 | res <- m | ||
117 | return $ Just res | ||
118 | |||
119 | -- | apply a test to successive elements of a vector, evaluates to true iff test passes for all pairs | ||
120 | successive_ :: Storable a => (a -> a -> Bool) -> Vector a -> Bool | ||
121 | successive_ t v = maybe False (\_ -> True) $ evalState (runMaybeT (mapVectorM_ step (subVector 1 (dim v - 1) v))) (v @> 0) | ||
122 | where step e = do | ||
123 | ep <- lift_maybe $ state_get | ||
124 | if t e ep | ||
125 | then lift_maybe $ state_put e | ||
126 | else (fail "successive_ test failed") | ||
127 | |||
128 | -- | operate on successive elements of a vector and return the resulting vector, whose length 1 less than that of the input | ||
129 | successive :: (Storable a, Storable b) => (a -> a -> b) -> Vector a -> Vector b | ||
130 | successive f v = evalState (mapVectorM step (subVector 1 (dim v - 1) v)) (v @> 0) | ||
131 | where step e = do | ||
132 | ep <- state_get | ||
133 | state_put e | ||
134 | return $ f ep e | ||
85 | 135 | ||
136 | ------------------------------------------------------------------- | ||