@@ -9,6 +9,9 @@ module Data.Array
9
9
( singleton
10
10
, (..), range
11
11
, replicate
12
+ , replicateM
13
+ , some
14
+ , many
12
15
13
16
, null
14
17
, length
@@ -36,6 +39,7 @@ module Data.Array
36
39
, concat
37
40
, concatMap
38
41
, filter
42
+ , filterM
39
43
, mapMaybe
40
44
, catMaybes
41
45
@@ -65,9 +69,9 @@ module Data.Array
65
69
, zipWithA
66
70
, zip
67
71
, unzip
68
- ) where
69
72
70
- import Prelude
73
+ , foldM
74
+ ) where
71
75
72
76
import Control.Alt (Alt , (<|>))
73
77
import Control.Alternative (Alternative )
@@ -101,6 +105,28 @@ infix 8 ..
101
105
-- | Create an array with repeated instances of a value.
102
106
foreign import replicate :: forall a . Int -> a -> Array a
103
107
108
+ -- | Perform a monadic action `n` times collecting all of the results.
109
+ replicateM :: forall m a . (Monad m ) => Int -> m a -> m (Array a )
110
+ replicateM n m | n < 1 = return []
111
+ | otherwise = do a <- m
112
+ as <- replicateM (n - 1 ) m
113
+ return (a : as)
114
+
115
+ -- | Attempt a computation multiple times, requiring at least one success.
116
+ -- |
117
+ -- | The `Lazy` constraint is used to generate the result lazily, to ensure
118
+ -- | termination.
119
+ some :: forall f a . (Alternative f , Lazy (f (Array a ))) => f a -> f (Array a )
120
+ some v = (:) <$> v <*> defer (\_ -> many v)
121
+
122
+ -- | Attempt a computation multiple times, returning as many successful results
123
+ -- | as possible (possibly zero).
124
+ -- |
125
+ -- | The `Lazy` constraint is used to generate the result lazily, to ensure
126
+ -- | termination.
127
+ many :: forall f a . (Alternative f , Lazy (f (Array a ))) => f a -> f (Array a )
128
+ many v = some v <|> pure []
129
+
104
130
-- ------------------------------------------------------------------------------
105
131
-- Array size ------------------------------------------------------------------
106
132
-- ------------------------------------------------------------------------------
@@ -255,6 +281,20 @@ concatMap = flip bind
255
281
-- | creating a new array.
256
282
foreign import filter :: forall a . (a -> Boolean ) -> Array a -> Array a
257
283
284
+ -- | Filter where the predicate returns a monadic `Boolean`.
285
+ -- |
286
+ -- | ```purescript
287
+ -- | powerSet :: forall a. [a] -> [[a]]
288
+ -- | powerSet = filterM (const [true, false])
289
+ -- | ```
290
+ filterM :: forall a m . (Monad m ) => (a -> m Boolean ) -> Array a -> m (Array a )
291
+ filterM p = uncons' (\_ -> pure [] ) \x xs -> do
292
+ b <- p x
293
+ xs' <- filterM p xs
294
+ return if b
295
+ then x : xs'
296
+ else xs'
297
+
258
298
-- | Apply a function to each element in an array, keeping only the results
259
299
-- | which contain a value, creating a new array.
260
300
mapMaybe :: forall a b . (a -> Maybe b ) -> Array a -> Array b
@@ -430,6 +470,18 @@ unzip :: forall a b. Array (Tuple a b) -> Tuple (Array a) (Array b)
430
470
unzip = uncons' (\_ -> Tuple [] [] ) \(Tuple a b) ts -> case unzip ts of
431
471
Tuple as bs -> Tuple (a : as) (b : bs)
432
472
473
+ -- ------------------------------------------------------------------------------
474
+ -- Folding ---------------------------------------------------------------------
475
+ -- ------------------------------------------------------------------------------
476
+
477
+ -- | Perform a fold using a monadic step function.
478
+ foldM :: forall m a b . (Monad m ) => (a -> b -> m a ) -> a -> Array b -> m a
479
+ foldM f a = uncons' (\_ -> return a) (\b bs -> f a b >>= \a' -> foldM f a' bs)
480
+
481
+ foreign import foldrArray :: forall a b . (a -> b -> b ) -> b -> Array a -> b
482
+
483
+ foreign import foldlArray :: forall a b . (b -> a -> b ) -> b -> Array a -> b
484
+
433
485
-- ------------------------------------------------------------------------------
434
486
-- Non-Prelude instances -------------------------------------------------------
435
487
-- ------------------------------------------------------------------------------
@@ -444,5 +496,14 @@ instance alternativeArray :: Alternative Array
444
496
445
497
instance monadPlusArray :: MonadPlus Array
446
498
499
+ instance foldableArray :: Foldable Array where
500
+ foldr f z xs = foldrArray f z xs
501
+ foldl f z xs = foldlArray f z xs
502
+ foldMap f xs = foldr (\x acc -> f x <> acc) mempty xs
503
+
504
+ instance traversableArray :: Traversable Array where
505
+ traverse f = uncons' (\_ -> pure [] ) (\x xs -> (:) <$> (f x) <*> traverse f xs)
506
+ sequence = uncons' (\_ -> pure [] ) (\x xs -> (:) <$> x <*> sequence xs)
507
+
447
508
instance invariantArray :: Invariant Array where
448
509
imap = imapF
0 commit comments