Skip to content

Commit dd9b949

Browse files
committed
Merge pull request #55 from hdgarrood/from-foldable
Add fromFoldable
2 parents 971c77f + 62c67db commit dd9b949

File tree

4 files changed

+66
-6
lines changed

4 files changed

+66
-6
lines changed

.jshintrc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"futurehostile": true,
88
"strict": "global",
99
"latedef": true,
10-
"maxparams": 1,
1110
"noarg": true,
1211
"nocomma": true,
1312
"nonew": true,

src/Data/Array.js

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,36 @@ exports.replicate = function (n) {
2828
};
2929
};
3030

31+
exports.fromFoldableImpl = (function () {
32+
function Cons (head, tail) {
33+
this.head = head;
34+
this.tail = tail;
35+
}
36+
var emptyList = {};
37+
38+
function curryCons (head) {
39+
return function (tail) {
40+
return new Cons(head, tail);
41+
};
42+
}
43+
44+
function listToArray (list) {
45+
var result = [];
46+
var count = 0;
47+
while (list !== emptyList) {
48+
result[count++] = list.head;
49+
list = list.tail;
50+
}
51+
return result;
52+
}
53+
54+
return function (foldr) {
55+
return function (xs) {
56+
return listToArray(foldr(curryCons)(emptyList)(xs));
57+
};
58+
};
59+
})();
60+
3161
//------------------------------------------------------------------------------
3262
// Array size ------------------------------------------------------------------
3363
//------------------------------------------------------------------------------
@@ -195,7 +225,6 @@ exports.partition = function (f) {
195225

196226
exports.sortImpl = function (f) {
197227
return function (l) {
198-
/* jshint maxparams: 2 */
199228
return l.slice().sort(function (x, y) {
200229
return f(x)(y);
201230
});

src/Data/Array.purs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module Data.Array
3434
, replicateM
3535
, some
3636
, many
37+
, fromFoldable
3738

3839
, null
3940
, length
@@ -107,7 +108,7 @@ import Control.Alt ((<|>))
107108
import Control.Alternative (class Alternative)
108109
import Control.Lazy (class Lazy, defer)
109110

110-
import Data.Foldable (foldl)
111+
import Data.Foldable (class Foldable, foldl, foldr)
111112
import Data.Maybe (Maybe(..), maybe, isJust, fromJust)
112113
import Data.Traversable (sequence)
113114
import Data.Tuple (Tuple(..))
@@ -148,6 +149,12 @@ some v = (:) <$> v <*> defer (\_ -> many v)
148149
many :: forall f a. (Alternative f, Lazy (f (Array a))) => f a -> f (Array a)
149150
many v = some v <|> pure []
150151

152+
-- | Construct an `Array` from any `Foldable` structure.
153+
fromFoldable :: forall f a. (Foldable f) => f a -> Array a
154+
fromFoldable = fromFoldableImpl foldr
155+
156+
foreign import fromFoldableImpl :: forall f a. (forall b. (a -> b -> b) -> b -> f a -> b) -> f a -> Array a
157+
151158
--------------------------------------------------------------------------------
152159
-- Array size ------------------------------------------------------------------
153160
--------------------------------------------------------------------------------

test/Test/Data/Array.purs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import Prelude
44

55
import Control.Monad.Eff (Eff)
66
import Control.Monad.Eff.Console (log, CONSOLE)
7+
import Data.Foldable (for_, foldMapDefaultR, class Foldable, all)
8+
import Test.Assert (assert)
79

8-
import Data.Array (range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, init, tail, last, head, insertBy, insert, snoc, (:), length, null, replicate, replicateM, singleton)
10+
import Data.Array (range, foldM, unzip, zip, zipWithA, zipWith, intersectBy, intersect, (\\), deleteBy, delete, unionBy, union, nubBy, nub, groupBy, group', group, span, dropWhile, drop, takeWhile, take, sortBy, sort, catMaybes, mapMaybe, filterM, filter, concat, concatMap, reverse, alterAt, modifyAt, updateAt, deleteAt, insertAt, findLastIndex, findIndex, elemLastIndex, elemIndex, (!!), uncons, init, tail, last, head, insertBy, insert, snoc, (:), length, null, replicate, replicateM, singleton, fromFoldable)
911
import Data.Maybe (Maybe(..), isNothing, fromJust)
1012
import Data.Tuple (Tuple(..))
1113

@@ -44,8 +46,8 @@ testArray = do
4446
assert $ replicateM (-1) (Just 1) == Just []
4547

4648
log "replicateM should be stack safe"
47-
let n = 50000
48-
assert $ replicateM n (Just unit) == Just (replicate n unit)
49+
for_ [1, 1000, 2000, 20000, 50000] \n -> do
50+
assert $ replicateM n (Just unit) == Just (replicate n unit)
4951

5052
-- some
5153
-- many
@@ -292,6 +294,17 @@ testArray = do
292294
assert $ foldM (\x y -> Just (x + y)) 0 (range 1 10) == Just 55
293295
assert $ foldM (\_ _ -> Nothing) 0 (range 1 10) == Nothing
294296

297+
log "fromFoldable"
298+
for_ [[], [1], [1,2], [1,2,3,4,5]] \xs -> do
299+
assert $ fromFoldable xs == xs
300+
301+
log "fromFoldable is stack safe"
302+
for_ [1, 1000, 10000, 20000, 50000] \n -> do
303+
let elem = 0
304+
let arr = fromFoldable (Replicated n elem)
305+
assert $ length arr == n
306+
assert $ all (_ == elem) arr
307+
295308
nil :: Array Int
296309
nil = []
297310

@@ -300,3 +313,15 @@ odd n = n `mod` 2 /= zero
300313

301314
doubleAndOrig :: Int -> Array Int
302315
doubleAndOrig x = [x * 2, x]
316+
317+
data Replicated a = Replicated Int a
318+
319+
instance foldableReplicated :: Foldable Replicated where
320+
foldr f z (Replicated n x) = applyN n (f x) z
321+
foldl f z (Replicated n x) = applyN n (flip f x) z
322+
foldMap = foldMapDefaultR
323+
324+
applyN :: forall a. Int -> (a -> a) -> a -> a
325+
applyN n f x
326+
| n <= 0 = x
327+
| otherwise = applyN (n - 1) f (f x)

0 commit comments

Comments
 (0)