@@ -20,7 +20,7 @@
20module Main (main) where
20module Main (main) where
22import Control.DeepSeq (NFData(..))
22import Control.DeepSeq (NFData(..))
23−import Control.Exception (SomeException)
23+import Control.Exception (SomeException, ErrorCall, try)
24import Streamly.Internal.Data.Unfold (Unfold)
24import Streamly.Internal.Data.Unfold (Unfold)
25import System.IO (Handle, hClose)
25import System.IO (Handle, hClose)
26import System.Random (randomRIO)
26import System.Random (randomRIO)
@@ -397,29 +397,13 @@ teeZipWith size start =
397 drainProductDefault (size + start) (UF.teeZipWith (+)) start
397 drainProductDefault (size + start) (UF.teeZipWith (+)) start
399-------------------------------------------------------------------------------
399-------------------------------------------------------------------------------
400−-- Nested
400+-- Applicative
401-------------------------------------------------------------------------------
401-------------------------------------------------------------------------------
403−{-# INLINE concatMapM #-}
404−concatMapM :: Monad m => Int -> Int -> m ()
405−concatMapM size start =
406− drainGeneration (UF.concatMapM unfoldInGen unfoldOut) start
411− sizeInner = size `div` sizeOuter
415− $ UF.supply (UF.enumerateFromToIntegral (i + sizeInner)) i
417− unfoldOut = UF.enumerateFromToIntegral (start + sizeOuter)
419{-# INLINE toNullAp #-}
403{-# INLINE toNullAp #-}
420toNullAp :: Monad m => Int -> Int -> m ()
404toNullAp :: Monad m => Int -> Int -> m ()
421−toNullAp linearCount start =
405+toNullAp value start =
422− let end = start + Nested.nestedCount2 linearCount
406+ let end = start + nthRoot 2 value
423 s = Nested.source end
407 s = Nested.source end
424 in UF.fold ((+) <$> s <*> s) FL.drain start
408 in UF.fold ((+) <$> s <*> s) FL.drain start
@@ -431,6 +415,128 @@ _apDiscardFst = undefined
431_apDiscardSnd :: Int -> Int -> m ()
415_apDiscardSnd :: Int -> Int -> m ()
432_apDiscardSnd = undefined
416_apDiscardSnd = undefined
418+-------------------------------------------------------------------------------
420+-------------------------------------------------------------------------------
422+nthRoot :: Double -> Int -> Int
423+nthRoot n value = round (fromIntegral value**(1/n))
425+{-# INLINE concatMapM #-}
426+concatMapM :: Monad m => Int -> Int -> m ()
427+concatMapM value start =
428+ val `seq` drainGeneration (UF.concatMapM unfoldInGen unfoldOut) start
432+ val = nthRoot 2 value
433+ unfoldInGen i = return (UF.enumerateFromToIntegral (i + val))
434+ unfoldOut = UF.enumerateFromToIntegral (start + val)
436+{-# INLINE toNull #-}
437+toNull :: Monad m => Int -> Int -> m ()
439+ let end = start + nthRoot 2 value
440+ src = Nested.source end
445+ in UF.fold u FL.drain start
448+{-# INLINE toNull3 #-}
449+toNull3 :: Monad m => Int -> Int -> m ()
450+toNull3 value start =
451+ let end = start + nthRoot 3 value
452+ src = Nested.source end
458+ in UF.fold u FL.drain start
460+{-# INLINE toList #-}
461+toList :: Monad m => Int -> Int -> m [Int]
462+toList value start = do
463+ let end = start + nthRoot 2 value
464+ src = Nested.source end
469+ in UF.fold u FL.toList start
471+{-# INLINE toListSome #-}
472+toListSome :: Monad m => Int -> Int -> m [Int]
473+toListSome value start = do
474+ let end = start + nthRoot 2 value
475+ src = Nested.source end
480+ in UF.fold (UF.take 1000 u) FL.toList start
482+{-# INLINE filterAllOut #-}
483+filterAllOut :: Monad m => Int -> Int -> m ()
484+filterAllOut value start = do
485+ let end = start + nthRoot 2 value
486+ src = Nested.source end
493+ else UF.nilM (return . const ())
494+ in UF.fold u FL.drain start
496+{-# INLINE filterAllIn #-}
497+filterAllIn :: Monad m => Int -> Int -> m ()
498+filterAllIn value start = do
499+ let end = start + nthRoot 2 value
500+ src = Nested.source end
507+ else UF.nilM (return . const ())
508+ in UF.fold u FL.drain start
510+{-# INLINE filterSome #-}
511+filterSome :: Monad m => Int -> Int -> m ()
512+filterSome value start = do
513+ let end = start + nthRoot 2 value
514+ src = Nested.source end
521+ else UF.nilM (return . const ())
522+ in UF.fold u FL.drain start
524+{-# INLINE breakAfterSome #-}
525+breakAfterSome :: Int -> Int -> IO ()
526+breakAfterSome value start =
527+ let end = start + nthRoot 2 value
528+ src = Nested.source end
537+ (_ :: Either ErrorCall ()) <- try $ UF.fold u FL.drain start
434-------------------------------------------------------------------------------
540-------------------------------------------------------------------------------
435-- Benchmarks
541-- Benchmarks
436-------------------------------------------------------------------------------
542-------------------------------------------------------------------------------
@@ -529,29 +635,30 @@ o_1_space_zip size =
529o_1_space_nested :: Int -> [Benchmark]
635o_1_space_nested :: Int -> [Benchmark]
530o_1_space_nested size =
636o_1_space_nested size =
532− "outer-product"
638+ "nested"
533− [ benchIO "toNullAp" $ toNullAp size
639+ [ benchIO "(<*>) (sqrt n x sqrt n)" $ toNullAp size
534− , benchIO "toNull" $ Nested.toNull size
535− , benchIO "toNull3" $ Nested.toNull3 size
536− , benchIO "concat" $ Nested.concat size
537− , benchIO "breakAfterSome" $ Nested.breakAfterSome size
538− , benchIO "filterAllOut" $ Nested.filterAllOut size
539− , benchIO "filterAllIn" $ Nested.filterAllIn size
540− , benchIO "filterSome" $ Nested.filterSome size
541− , benchIO "concatMapM (100 x n/100)" $ concatMapM size
542 -- Unimplemented
640 -- Unimplemented
543− -- , benchIO "ap" $ ap size
544 -- , benchIO "apDiscardFst" $ apDiscardFst size
641 -- , benchIO "apDiscardFst" $ apDiscardFst size
545 -- , benchIO "apDiscardSnd" $ apDiscardSnd size
642 -- , benchIO "apDiscardSnd" $ apDiscardSnd size
644+ , benchIO "concatMapM (sqrt n x sqrt n)" $ concatMapM size
645+ , benchIO "(>>=) (sqrt n x sqrt n)" $ toNull size
646+ , benchIO "(>>=) (cubert n x cubert n x cubert n)" $ toNull3 size
647+ , benchIO "breakAfterSome" $ breakAfterSome size
648+ , benchIO "filterAllOut" $ filterAllOut size
649+ , benchIO "filterAllIn" $ filterAllIn size
650+ , benchIO "filterSome" $ filterSome size
652+ , benchIO "concat" $ Nested.concat size
549o_n_space_nested :: Int -> [Benchmark]
656o_n_space_nested :: Int -> [Benchmark]
550o_n_space_nested size =
657o_n_space_nested size =
552− "outer-product"
659+ "nested"
553− [ benchIO "toList" $ Nested.toList size
660+ [ benchIO "toList" $ toList size
554− , benchIO "toListSome" $ Nested.toListSome size
661+ , benchIO "toListSome" $ toListSome size