@@ -271,53 +271,67 @@ instance Monad Seq where
271
271
272
272
instance Applicative Seq where
273
273
pure = singleton
274
-
275
- Seq Empty <*> xs = xs `seq` empty
276
- fs <*> Seq Empty = fs `seq` empty
277
- fs <*> Seq (Single (Elem x)) = fmap ($ x) fs
278
- fs <*> xs
279
- | length fs < 4 = foldl' add empty fs
280
- where add ys f = ys >< fmap f xs
281
- fs <*> xs | length xs < 4 = apShort fs xs
282
- fs <*> xs = apty fs xs
283
-
284
274
xs *> ys = replicateSeq (length xs) ys
285
275
286
- -- <*> when the length of the first argument is at least two and
287
- -- the length of the second is two or three.
288
- apShort :: Seq (a -> b ) -> Seq a -> Seq b
289
- apShort (Seq fs) xs = Seq $ case toList xs of
290
- [a,b] -> ap2FT fs (a,b)
291
- [a,b,c] -> ap3FT fs (a,b,c)
292
- _ -> error " apShort: not 2-3"
293
-
294
- ap2FT :: FingerTree (Elem (a -> b )) -> (a ,a ) -> FingerTree (Elem b )
295
- ap2FT fs (x,y) = Deep (size fs * 2 )
276
+ fs <*> xs = case viewl fs of
277
+ EmptyL -> empty
278
+ firstf :< fs' -> case viewr fs' of
279
+ EmptyR -> fmap firstf xs
280
+ Seq fs''FT :> lastf -> case (rigidify . (\ (Seq a) -> a)) xs of
281
+ RigidEmpty -> empty
282
+ RigidOne (Elem x) -> fmap ($ x) fs
283
+ RigidTwo (Elem x1) (Elem x2) ->
284
+ Seq $ ap2FT firstf fs''FT lastf (x1, x2)
285
+ RigidThree (Elem x1) (Elem x2) (Elem x3) ->
286
+ Seq $ ap3FT firstf fs''FT lastf (x1, x2, x3)
287
+ RigidFull r@ (Rigid s pr _m sf) -> Seq $
288
+ Deep (s * length fs)
289
+ (fmap (fmap firstf) (nodeToDigit pr))
290
+ (aptyMiddle (fmap firstf) (fmap lastf) fmap fs''FT r)
291
+ (fmap (fmap lastf) (nodeToDigit sf))
292
+
293
+
294
+ ap2FT :: (a -> b ) -> FingerTree (Elem (a -> b )) -> (a -> b ) -> (a ,a ) -> FingerTree (Elem b )
295
+ ap2FT firstf fs lastf (x,y) =
296
+ Deep (size fs * 2 + 4 )
296
297
(Two (Elem $ firstf x) (Elem $ firstf y))
297
- (mapMulFT 2 (\ (Elem f) -> Node2 2 (Elem (f x)) (Elem (f y))) m )
298
+ (mapMulFT 2 (\ (Elem f) -> Node2 2 (Elem (f x)) (Elem (f y))) fs )
298
299
(Two (Elem $ lastf x) (Elem $ lastf y))
299
- where
300
- (Elem firstf, m, Elem lastf) = trimTree fs
301
300
302
- ap3FT :: FingerTree (Elem (a -> b )) -> (a ,a ,a ) -> FingerTree (Elem b )
303
- ap3FT fs (x,y,z) = Deep (size fs * 3 )
301
+ ap3FT :: ( a -> b ) -> FingerTree (Elem (a -> b )) -> ( a -> b ) -> (a ,a ,a ) -> FingerTree (Elem b )
302
+ ap3FT firstf fs lastf (x,y,z) = Deep (size fs * 3 + 6 )
304
303
(Three (Elem $ firstf x) (Elem $ firstf y) (Elem $ firstf z))
305
- (mapMulFT 3 (\ (Elem f) -> Node3 3 (Elem (f x)) (Elem (f y)) (Elem (f z))) m )
304
+ (mapMulFT 3 (\ (Elem f) -> Node3 3 (Elem (f x)) (Elem (f y)) (Elem (f z))) fs )
306
305
(Three (Elem $ lastf x) (Elem $ lastf y) (Elem $ lastf z))
307
- where
308
- (Elem firstf, m, Elem lastf) = trimTree fs
309
-
310
- -- <*> when the length of each argument is at least four.
311
- apty :: Seq (a -> b ) -> Seq a -> Seq b
312
- apty (Seq fs) (Seq xs@ Deep {}) = Seq $
313
- Deep (s' * size fs)
314
- (fmap (fmap firstf) pr')
315
- (aptyMiddle (fmap firstf) (fmap lastf) fmap fs' xs')
316
- (fmap (fmap lastf) sf')
317
- where
318
- (Elem firstf, fs', Elem lastf) = trimTree fs
319
- xs'@ (Deep s' pr' _m' sf') = rigidify xs
320
- apty _ _ = error " apty: expects a Deep constructor"
306
+
307
+
308
+ data Rigidified a = RigidEmpty
309
+ | RigidOne a
310
+ | RigidTwo a a
311
+ | RigidThree a a a
312
+ | RigidFull (Rigid a )
313
+ #ifdef TESTING
314
+ deriving Show
315
+ #endif
316
+
317
+ data Rigid a = Rigid {- # UNPACK #-} !Int ! (Digit23 a ) (Thin (Node a )) ! (Digit23 a )
318
+ #ifdef TESTING
319
+ deriving Show
320
+ #endif
321
+
322
+ data Thin a = EmptyTh
323
+ | SingleTh a
324
+ | DeepTh {- # UNPACK #-} !Int ! (Digit12 a ) (Thin (Node a )) ! (Digit12 a )
325
+ #ifdef TESTING
326
+ deriving Show
327
+ #endif
328
+
329
+ data Digit12 a = One12 a | Two12 a a
330
+ #ifdef TESTING
331
+ deriving Show
332
+ #endif
333
+
334
+ type Digit23 a = Node a
321
335
322
336
-- | 'aptyMiddle' does most of the hard work of computing @fs<*>xs@.
323
337
-- It produces the center part of a finger tree, with a prefix corresponding
@@ -333,55 +347,56 @@ aptyMiddle
333
347
-> (c -> d )
334
348
-> ((a -> b ) -> c -> d )
335
349
-> FingerTree (Elem (a -> b ))
336
- -> FingerTree c
350
+ -> Rigid c
337
351
-> FingerTree (Node d )
352
+
338
353
-- Not at the bottom yet
354
+
339
355
aptyMiddle firstf
340
356
lastf
341
357
map23
342
358
fs
343
- (Deep s pr (Deep sm prm mm sfm) sf)
359
+ (Rigid s pr (DeepTh sm prm mm sfm) sf)
344
360
= Deep (sm + s * (size fs + 1 )) -- note: sm = s - size pr - size sf
345
- (fmap (fmap firstf) prm)
361
+ (fmap (fmap firstf) (digit12ToDigit prm) )
346
362
(aptyMiddle (fmap firstf)
347
363
(fmap lastf)
348
- (\ f -> fmap (map23 f) )
364
+ (fmap . map23 )
349
365
fs
350
- (Deep s (squashL pr prm) mm (squashR sfm sf)))
351
- (fmap (fmap lastf) sfm)
366
+ (Rigid s (squashL pr prm) mm (squashR sfm sf)))
367
+ (fmap (fmap lastf) (digit12ToDigit sfm))
368
+
369
+ -- At the bottom
370
+
371
+ aptyMiddle firstf
372
+ lastf
373
+ map23
374
+ fs
375
+ (Rigid s pr EmptyTh sf)
376
+ = deep
377
+ (One (fmap firstf sf))
378
+ (mapMulFT s (\ (Elem f) -> fmap (fmap (map23 f)) converted) fs)
379
+ (One (fmap lastf pr))
380
+ where converted = node2 pr sf
352
381
353
- -- At the bottom. Note that these appendTree0 calls are very cheap, because in
354
- -- each case, one of the arguments is guaranteed to be Empty or Single.
355
382
aptyMiddle firstf
356
383
lastf
357
384
map23
358
385
fs
359
- (Deep s pr m sf)
360
- = fmap (fmap firstf) m `appendTree0`
361
- ((fmap firstf (digitToNode sf)
362
- `consTree` middle)
363
- `snocTree` fmap lastf (digitToNode pr))
364
- `appendTree0` fmap (fmap lastf) m
365
- where middle = case trimTree $ mapMulFT s (\ (Elem f) -> fmap (fmap (map23 f)) converted) fs of
366
- (firstMapped, restMapped, lastMapped) ->
367
- Deep (size firstMapped + size restMapped + size lastMapped)
368
- (nodeToDigit firstMapped) restMapped (nodeToDigit lastMapped)
369
- converted = case m of
370
- Empty -> Node2 s lconv rconv
371
- Single q -> Node3 s lconv q rconv
372
- Deep {} -> error " aptyMiddle: impossible"
373
- lconv = digitToNode pr
374
- rconv = digitToNode sf
375
-
376
- aptyMiddle _ _ _ _ _ = error " aptyMiddle: expected Deep finger tree"
386
+ (Rigid s pr (SingleTh q) sf)
387
+ = deep
388
+ (Two (fmap firstf q) (fmap firstf sf))
389
+ (mapMulFT s (\ (Elem f) -> fmap (fmap (map23 f)) converted) fs)
390
+ (Two (fmap lastf pr) (fmap lastf q))
391
+ where converted = node3 pr q sf
377
392
378
393
{-# SPECIALIZE
379
394
aptyMiddle
380
395
:: (Node c -> d)
381
396
-> (Node c -> d)
382
397
-> ((a -> b) -> Node c -> d)
383
398
-> FingerTree (Elem (a -> b))
384
- -> FingerTree (Node c)
399
+ -> Rigid (Node c)
385
400
-> FingerTree (Node d)
386
401
#-}
387
402
{-# SPECIALIZE
@@ -390,33 +405,24 @@ aptyMiddle _ _ _ _ _ = error "aptyMiddle: expected Deep finger tree"
390
405
-> (Elem c -> d)
391
406
-> ((a -> b) -> Elem c -> d)
392
407
-> FingerTree (Elem (a -> b))
393
- -> FingerTree (Elem c)
408
+ -> Rigid (Elem c)
394
409
-> FingerTree (Node d)
395
410
#-}
396
411
397
- digitToNode :: Sized a => Digit a -> Node a
398
- digitToNode (Two a b) = node2 a b
399
- digitToNode (Three a b c) = node3 a b c
400
- digitToNode _ = error " digitToNode: not representable as a node"
401
-
402
- type Digit23 = Digit
403
- type Digit12 = Digit
412
+ digit12ToDigit :: Digit12 a -> Digit a
413
+ digit12ToDigit (One12 a) = One a
414
+ digit12ToDigit (Two12 a b) = Two a b
404
415
405
416
-- Squash the first argument down onto the left side of the second.
406
417
squashL :: Sized a => Digit23 a -> Digit12 (Node a ) -> Digit23 (Node a )
407
- squashL (Two a b) (One n) = Two (node2 a b) n
408
- squashL (Two a b) (Two n1 n2) = Three (node2 a b) n1 n2
409
- squashL (Three a b c) (One n) = Two (node3 a b c) n
410
- squashL (Three a b c) (Two n1 n2) = Three (node3 a b c) n1 n2
411
- squashL _ _ = error " squashL: wrong digit types"
418
+ squashL m (One12 n) = node2 m n
419
+ squashL m (Two12 n1 n2) = node3 m n1 n2
412
420
413
421
-- Squash the second argument down onto the right side of the first
414
422
squashR :: Sized a => Digit12 (Node a ) -> Digit23 a -> Digit23 (Node a )
415
- squashR (One n) (Two a b) = Two n (node2 a b)
416
- squashR (Two n1 n2) (Two a b) = Three n1 n2 (node2 a b)
417
- squashR (One n) (Three a b c) = Two n (node3 a b c)
418
- squashR (Two n1 n2) (Three a b c) = Three n1 n2 (node3 a b c)
419
- squashR _ _ = error " squashR: wrong digit types"
423
+ squashR (One12 n) m = node2 n m
424
+ squashR (Two12 n1 n2) m = node3 n1 n2 m
425
+
420
426
421
427
-- | /O(m*n)/ (incremental) Takes an /O(m)/ function and a finger tree of size
422
428
-- /n/ and maps the function over the tree leaves. Unlike the usual 'fmap', the
@@ -435,72 +441,81 @@ mapMulNode mul f (Node2 s a b) = Node2 (mul * s) (f a) (f b)
435
441
mapMulNode mul f (Node3 s a b c) = Node3 (mul * s) (f a) (f b) (f c)
436
442
437
443
438
- trimTree :: Sized a => FingerTree a -> (a , FingerTree a , a )
439
- trimTree Empty = error " trim: empty tree"
440
- trimTree Single {} = error " trim: singleton"
441
- trimTree t = case splitTree 0 t of
442
- Split _ hd r ->
443
- case splitTree (size r - 1 ) r of
444
- Split m tl _ -> (hd, m, tl)
444
+ -- rigidify :: Seq a -> Rigidified (Elem a)
445
+ -- rigidify (Seq xs) = rigidify' xs
445
446
446
447
-- | /O(log n)/ (incremental) Takes the extra flexibility out of a 'FingerTree'
447
448
-- to make it a genuine 2-3 finger tree. The result of 'rigidify' will have
448
449
-- only 'Two' and 'Three' digits at the top level and only 'One' and 'Two'
449
450
-- digits elsewhere. It gives an error if the tree has fewer than four
450
451
-- elements.
451
- rigidify :: Sized a => FingerTree a -> FingerTree a
452
+ rigidify :: FingerTree ( Elem a ) -> Rigidified ( Elem a )
452
453
-- Note that 'rigidify' may call itself, but it will do so at most
453
454
-- once: each call to 'rigidify' will either fix the whole tree or fix one digit
454
455
-- and leave the other alone. The patterns below just fix up the top level of
455
456
-- the tree; 'rigidify' delegates the hard work to 'thin'.
456
457
457
458
-- The top of the tree is fine.
458
- rigidify (Deep s pr@ Two {} m sf@ Three {}) = Deep s pr (thin m) sf
459
- rigidify (Deep s pr@ Three {} m sf@ Three {}) = Deep s pr (thin m) sf
460
- rigidify (Deep s pr@ Two {} m sf@ Two {}) = Deep s pr (thin m) sf
461
- rigidify (Deep s pr@ Three {} m sf@ Two {}) = Deep s pr (thin m) sf
459
+
460
+ rigidify (Deep s (Two a b) m (Three c d e)) =
461
+ RigidFull $ Rigid s (node2 a b) (thin m) (node3 c d e)
462
+ rigidify (Deep s (Three a b c) m (Three d e f)) =
463
+ RigidFull $ Rigid s (node3 a b c) (thin m) (node3 d e f)
464
+ rigidify (Deep s (Two a b) m (Two c d)) =
465
+ RigidFull $ Rigid s (node2 a b) (thin m) (node2 c d)
466
+ rigidify (Deep s (Three a b c) m (Two d e)) =
467
+ RigidFull $ Rigid s (node3 a b c) (thin m) (node2 d e)
462
468
463
469
-- One of the Digits is a Four.
464
470
rigidify (Deep s (Four a b c d) m sf) =
465
471
rigidify $ Deep s (Two a b) (node2 c d `consTree` m) sf
472
+
466
473
rigidify (Deep s pr m (Four a b c d)) =
467
474
rigidify $ Deep s pr (m `snocTree` node2 a b) (Two c d)
468
475
469
- -- One of the Digits is a One. If the middle is empty, we can only rigidify the
470
- -- tree if the other Digit is a Three.
471
- rigidify (Deep s (One a) Empty (Three b c d)) = Deep s (Two a b) Empty (Two c d)
472
- rigidify (Deep s (One a) m sf) = rigidify $ case viewLTree m of
473
- Just2 (Node2 _ b c) m' -> Deep s (Three a b c) m' sf
474
- Just2 (Node3 _ b c d) m' -> Deep s (Two a b) (node2 c d `consTree` m') sf
475
- Nothing2 -> error " rigidify: small tree"
476
- rigidify (Deep s (Three a b c) Empty (One d)) = Deep s (Two a b) Empty (Two c d)
477
- rigidify (Deep s pr m (One e)) = rigidify $ case viewRTree m of
478
- Just2 m' (Node2 _ a b) -> Deep s pr m' (Three a b e)
479
- Just2 m' (Node3 _ a b c) -> Deep s pr (m' `snocTree` node2 a b) (Two c e)
480
- Nothing2 -> error " rigidify: small tree"
481
- rigidify Empty = error " rigidify: empty tree"
482
- rigidify Single {} = error " rigidify: singleton"
476
+ -- One of the Digits is a One.
477
+ rigidify (Deep s (One a) m sf) = case viewLTree m of
478
+ Just2 (Node2 _ b c) m' -> rigidify $ Deep s (Three a b c) m' sf
479
+ Just2 (Node3 _ b c d) m' -> rigidify $ Deep s (Two a b) (node2 c d `consTree` m') sf
480
+ Nothing2 -> case sf of
481
+ One b -> RigidTwo a b
482
+ Two b c -> RigidThree a b c
483
+ Three b c d -> RigidFull $ Rigid s (node2 a b) EmptyTh (node2 c d)
484
+ Four b c d e -> RigidFull $ Rigid s (node3 a b c) EmptyTh (node2 d e)
485
+
486
+ rigidify (Deep s pr m (One e)) = case viewRTree m of
487
+ Just2 m' (Node2 _ a b) -> rigidify $ Deep s pr m' (Three a b e)
488
+ Just2 m' (Node3 _ a b c) -> rigidify $ Deep s pr (m' `snocTree` node2 a b) (Two c e)
489
+ Nothing2 -> case pr of
490
+ One a -> RigidTwo a e
491
+ Two a b -> RigidThree a b e
492
+ Three a b c -> RigidFull $ Rigid s (node2 a b) EmptyTh (node2 c e)
493
+ Four a b c d -> RigidFull $ Rigid s (node3 a b c) EmptyTh (node2 d e)
494
+
495
+ rigidify Empty = RigidEmpty
496
+
497
+ rigidify (Single q) = RigidOne q
498
+
483
499
484
500
-- | /O(log n)/ (incremental) Rejigger a finger tree so the digits are all ones
485
501
-- and twos.
486
- thin :: Sized a => FingerTree a -> FingerTree a
502
+ thin :: Sized a => FingerTree a -> Thin a
487
503
-- Note that 'thin12' will produce a 'Deep' constructor immediately before
488
504
-- recursively calling 'thin'.
489
- thin Empty = Empty
490
- thin (Single a) = Single a
491
- thin t @ (Deep s pr m sf) =
505
+ thin Empty = EmptyTh
506
+ thin (Single a) = SingleTh a
507
+ thin (Deep s pr m sf) =
492
508
case pr of
493
- One {} -> thin12 t
494
- Two {} -> thin12 t
495
- Three a b c -> thin12 $ Deep s (One a) (node2 b c `consTree` m) sf
496
- Four a b c d -> thin12 $ Deep s (Two a b) (node2 c d `consTree` m) sf
509
+ One a -> thin12 s ( One12 a) m sf
510
+ Two a b -> thin12 s ( Two12 a b) m sf
511
+ Three a b c -> thin12 s (One12 a) (node2 b c `consTree` m) sf
512
+ Four a b c d -> thin12 s (Two12 a b) (node2 c d `consTree` m) sf
497
513
498
- thin12 :: Sized a => FingerTree a -> FingerTree a
499
- thin12 (Deep s pr m sf@ One {}) = Deep s pr (thin m) sf
500
- thin12 (Deep s pr m sf@ Two {}) = Deep s pr (thin m) sf
501
- thin12 (Deep s pr m (Three a b c)) = Deep s pr (thin $ m `snocTree` node2 a b) (One c)
502
- thin12 (Deep s pr m (Four a b c d)) = Deep s pr (thin $ m `snocTree` node2 a b) (Two c d)
503
- thin12 _ = error " thin12 expects a Deep FingerTree."
514
+ thin12 :: Sized a => Int -> Digit12 a -> FingerTree (Node a ) -> Digit a -> Thin a
515
+ thin12 s pr m (One a) = DeepTh s pr (thin m) (One12 a)
516
+ thin12 s pr m (Two a b) = DeepTh s pr (thin m) (Two12 a b)
517
+ thin12 s pr m (Three a b c) = DeepTh s pr (thin $ m `snocTree` node2 a b) (One12 c)
518
+ thin12 s pr m (Four a b c d) = DeepTh s pr (thin $ m `snocTree` node2 a b) (Two12 c d)
504
519
505
520
506
521
instance MonadPlus Seq where
@@ -975,9 +990,7 @@ Seq xs >< Seq ys = Seq (appendTree0 xs ys)
975
990
976
991
-- The appendTree/addDigits gunk below is machine generated
977
992
978
- {-# SPECIALIZE appendTree0 :: FingerTree (Elem a) -> FingerTree (Elem a) -> FingerTree (Elem a) #-}
979
- {-# SPECIALIZE appendTree0 :: FingerTree (Node a) -> FingerTree (Node a) -> FingerTree (Node a) #-}
980
- appendTree0 :: Sized a => FingerTree a -> FingerTree a -> FingerTree a
993
+ appendTree0 :: FingerTree (Elem a ) -> FingerTree (Elem a ) -> FingerTree (Elem a )
981
994
appendTree0 Empty xs =
982
995
xs
983
996
appendTree0 xs Empty =
0 commit comments