@@ -277,7 +277,7 @@ apShort :: Seq (a -> b) -> Seq a -> Seq b
277
277
apShort (Seq fs) xs = Seq $ case toList xs of
278
278
[a,b] -> ap2FT fs (a,b)
279
279
[a,b,c] -> ap3FT fs (a,b,c)
280
- _ -> error " apShort: not 2-6 "
280
+ _ -> error " apShort: not 2-3 "
281
281
282
282
ap2FT :: FingerTree (Elem (a -> b )) -> (a ,a ) -> FingerTree (Elem b )
283
283
ap2FT fs (x,y) = Deep (size fs * 2 )
@@ -298,104 +298,85 @@ ap3FT fs (x,y,z) = Deep (size fs * 3)
298
298
-- <*> when the length of each argument is at least four.
299
299
apty :: Seq (a -> b ) -> Seq a -> Seq b
300
300
apty (Seq fs) (Seq xs@ Deep {}) = Seq $
301
- runApState (fmap firstf) (fmap lastf) fmap fs' (ApState xs' xs' xs')
301
+ Deep (s' * size fs)
302
+ (fmap (fmap firstf) pr')
303
+ (aptyMiddle (fmap firstf) (fmap lastf) fmap fs' xs')
304
+ (fmap (fmap lastf) sf')
302
305
where
303
306
(Elem firstf, fs', Elem lastf) = trimTree fs
304
- xs' = rigidify xs
307
+ xs'@ ( Deep s' pr' _m' sf') = rigidify xs
305
308
apty _ _ = error " apty: expects a Deep constructor"
306
309
307
- data ApState a = ApState (FingerTree a ) (FingerTree a ) (FingerTree a )
308
-
309
- -- | 'runApState' uses three copies of the @xs@ tree to produce the @fs<*>xs@
310
- -- tree. It pulls left digits off the left tree, right digits off the right tree,
311
- -- and squashes down the other four digits. Once it gets to the bottom, it turns
312
- -- the middle tree into a 2-3 tree, applies 'mapMulFT' to produce the main body,
313
- -- and glues all the pieces together.
314
- runApState
310
+ -- | 'aptyMiddle' does most of the hard work of computing @fs<*>xs@.
311
+ -- It produces the center part of a finger tree, with a prefix corresponding
312
+ -- to the prefix of @xs@ and a suffix corresponding to the suffix of @xs@
313
+ -- omitted; the missing suffix and prefix are added by the caller.
314
+ -- For the recursive call, it squashes the prefix and the suffix into
315
+ -- the center tree. Once it gets to the bottom, it turns the tree into
316
+ -- a 2-3 tree, applies 'mapMulFT' to produce the main body, and glues all
317
+ -- the pieces together.
318
+ aptyMiddle
315
319
:: Sized c =>
316
320
(c -> d )
317
321
-> (c -> d )
318
322
-> ((a -> b ) -> c -> d )
319
323
-> FingerTree (Elem (a -> b ))
320
- -> ApState c
321
- -> FingerTree d
324
+ -> FingerTree c
325
+ -> FingerTree ( Node d )
322
326
-- Not at the bottom yet
323
- runApState firstf
327
+ aptyMiddle firstf
324
328
lastf
325
329
map23
326
330
fs
327
- (ApState
328
- (Deep sl
329
- prl
330
- (Deep sml prml mml sfml)
331
- sfl)
332
- (Deep sm
333
- prm
334
- (Deep _smm prmm mmm sfmm)
335
- sfm)
336
- (Deep sr
337
- prr
338
- (Deep smr prmr mmr sfmr)
339
- sfr))
340
- = Deep (sl + sr + sm * size fs)
341
- (fmap firstf prl)
342
- (runApState (fmap firstf)
331
+ (Deep s pr (Deep sm prm mm sfm) sf)
332
+ = Deep (sm + s * (size fs + 1 )) -- note: sm = s - size pr - size sf
333
+ (fmap (fmap firstf) prm)
334
+ (aptyMiddle (fmap firstf)
343
335
(fmap lastf)
344
336
(\ f -> fmap (map23 f))
345
337
fs
346
- nextState)
347
- (fmap lastf sfr)
348
- where nextState =
349
- ApState
350
- (Deep (sml + size sfl) prml mml (squashR sfml sfl))
351
- (Deep sm (squashL prm prmm) mmm (squashR sfmm sfm))
352
- (Deep (smr + size prr) (squashL prr prmr) mmr sfmr)
338
+ (Deep s (squashL pr prm) mm (squashR sfm sf)))
339
+ (fmap (fmap lastf) sfm)
353
340
354
341
-- At the bottom
355
- runApState firstf
342
+ aptyMiddle firstf
356
343
lastf
357
344
map23
358
345
fs
359
- (ApState
360
- (Deep sl prl ml sfl)
361
- (Deep sm prm mm sfm)
362
- (Deep sr prr mr sfr))
363
- = Deep (sl + sr + sm * size fs)
364
- (fmap firstf prl)
365
- ((fmap (fmap firstf) ml `snocTree` fmap firstf (digitToNode sfl))
366
- `appendTree0` middle `appendTree0`
367
- (fmap lastf (digitToNode prr) `consTree` fmap (fmap lastf) mr))
368
- (fmap lastf sfr)
369
- where middle = case trimTree $ mapMulFT sm (\ (Elem f) -> fmap (fmap (map23 f)) converted) fs of
346
+ (Deep s pr m sf)
347
+ = (fmap (fmap firstf) m `snocTree` fmap firstf (digitToNode sf))
348
+ `appendTree0` middle `appendTree0`
349
+ (fmap lastf (digitToNode pr) `consTree` fmap (fmap lastf) m)
350
+ where middle = case trimTree $ mapMulFT s (\ (Elem f) -> fmap (fmap (map23 f)) converted) fs of
370
351
(firstMapped, restMapped, lastMapped) ->
371
352
Deep (size firstMapped + size restMapped + size lastMapped)
372
353
(nodeToDigit firstMapped) restMapped (nodeToDigit lastMapped)
373
- converted = case mm of
374
- Empty -> Node2 sm lconv rconv
375
- Single q -> Node3 sm lconv q rconv
376
- Deep {} -> error " runApState: a tree is shallower than the middle tree "
377
- lconv = digitToNode prm
378
- rconv = digitToNode sfm
354
+ converted = case m of
355
+ Empty -> Node2 s lconv rconv
356
+ Single q -> Node3 s lconv q rconv
357
+ Deep {} -> error " aptyMiddle: impossible "
358
+ lconv = digitToNode pr
359
+ rconv = digitToNode sf
379
360
380
- runApState _ _ _ _ _ = error " runApState: ApState must hold Deep finger trees of the same depth "
361
+ aptyMiddle _ _ _ _ _ = error " aptyMiddle: expected Deep finger tree "
381
362
382
363
{-# SPECIALIZE
383
- runApState
364
+ aptyMiddle
384
365
:: (Node c -> d)
385
366
-> (Node c -> d)
386
367
-> ((a -> b) -> Node c -> d)
387
368
-> FingerTree (Elem (a -> b))
388
- -> ApState (Node c)
389
- -> FingerTree d
369
+ -> FingerTree (Node c)
370
+ -> FingerTree (Node d)
390
371
#-}
391
372
{-# SPECIALIZE
392
- runApState
373
+ aptyMiddle
393
374
:: (Elem c -> d)
394
375
-> (Elem c -> d)
395
376
-> ((a -> b) -> Elem c -> d)
396
377
-> FingerTree (Elem (a -> b))
397
- -> ApState (Elem c)
398
- -> FingerTree d
378
+ -> FingerTree (Elem c)
379
+ -> FingerTree (Node d)
399
380
#-}
400
381
401
382
digitToNode :: Sized a => Digit a -> Node a
@@ -2096,16 +2077,9 @@ reverseNode f (Node3 s a b c) = Node3 s (f c) (f b) (f a)
2096
2077
-- Mapping with a splittable value
2097
2078
------------------------------------------------------------------------
2098
2079
2099
- -- For zipping, and probably also for (<*>), it is useful to build a result by
2080
+ -- For zipping, it is useful to build a result by
2100
2081
-- traversing a sequence while splitting up something else. For zipping, we
2101
- -- traverse the first sequence while splitting up the second [and third [and
2102
- -- fourth]]. For fs <*> xs, we hope to traverse
2103
- --
2104
- -- > replicate (length fs * length xs) ()
2105
- --
2106
- -- while splitting something essentially equivalent to
2107
- --
2108
- -- > fmap (\f -> fmap f xs) fs
2082
+ -- traverse the first sequence while splitting up the second.
2109
2083
--
2110
2084
-- What makes all this crazy code a good idea:
2111
2085
--
@@ -2129,8 +2103,8 @@ reverseNode f (Node3 s a b c) = Node3 s (f c) (f b) (f a)
2129
2103
-- they're actually needed. We do the same thing for Digits (splitting into
2130
2104
-- between one and four pieces) and Nodes (splitting into two or three). The
2131
2105
-- ultimate result is that we can index into, or split at, any location in zs
2132
- -- in O((log(min{i,n-i}))^2) time *immediately*, while still being able to
2133
- -- force all the thunks in O(n) time.
2106
+ -- in polylogarithmic time *immediately*, while still being able to force all
2107
+ -- the thunks in O(n) time.
2134
2108
--
2135
2109
-- Benchmark info, and alternatives:
2136
2110
--
0 commit comments