@@ -32,6 +32,7 @@ import Data.Traversable (class Traversable, traverse)
3232import Data.TraversableWithIndex (class TraversableWithIndex )
3333import Data.Tuple (Tuple (..), snd )
3434import Data.Unfoldable (class Unfoldable )
35+ import Partial.Unsafe (unsafePartial )
3536
3637data List a = Nil | Cons a (List a )
3738
@@ -79,33 +80,18 @@ instance functorList :: Functor List where
7980-- https://discuss.ocaml.org/t/a-new-list-map-that-is-both-stack-safe-and-fast/865
8081-- chunk sizes determined through experimentation
8182listMap :: forall a b . (a -> b ) -> List a -> List b
82- listMap f = startUnrolledMap unrollLimit where
83- -- iterate the unrolled map up to 200 times,
84- -- which hits up to 1000 elements
85- unrollLimit = 200
86-
87- startUnrolledMap :: Int -> List a -> List b
88- startUnrolledMap 0 (x : xs) = f x : chunkedRevMap xs
89- startUnrolledMap n (x1 : x2 : x3 : x4 : x5 : xs) =
90- f x1 : f x2 : f x3 : f x4 : f x5 : startUnrolledMap (n - 1 ) xs
91- startUnrolledMap n (x1 : x2 : x3 : x4 : xs) =
92- f x1 : f x2 : f x3 : f x4 : startUnrolledMap (n - 1 ) xs
93- startUnrolledMap n (x1 : x2 : x3 : xs) =
94- f x1 : f x2 : f x3 : startUnrolledMap (n - 1 ) xs
95- startUnrolledMap n (x1 : x2 : xs) =
96- f x1 : f x2 : startUnrolledMap (n - 1 ) xs
97- startUnrolledMap n (x : xs) = f x : startUnrolledMap (n - 1 ) xs
98-
99- startUnrolledMap _ Nil = Nil
100-
101- chunkedRevMap :: List a -> List b
102- chunkedRevMap = go Nil
83+ listMap f = chunkedRevMap Nil
84+ where
85+ chunkedRevMap :: List (List a ) -> List a -> List b
86+ chunkedRevMap chunksAcc chunk@(x1 : x2 : x3 : xs) =
87+ chunkedRevMap (chunk : chunksAcc) xs
88+ chunkedRevMap chunksAcc finalChunk =
89+ reverseUnrolledMap chunksAcc $ unsafePartial unrolledMap finalChunk
10390 where
104- go :: List (List a ) -> List a -> List b
105- go chunksAcc chunk@(x1 : x2 : x3 : xs) =
106- go (chunk : chunksAcc) xs
107- go chunksAcc finalChunk =
108- reverseUnrolledMap chunksAcc $ startUnrolledMap 0 finalChunk
91+ unrolledMap :: Partial => List a -> List b
92+ unrolledMap (x1 : x2 : Nil ) = f x1 : f x2 : Nil
93+ unrolledMap (x : Nil ) = f x : Nil
94+ unrolledMap Nil = Nil
10995
11096 reverseUnrolledMap :: List (List a ) -> List b -> List b
11197 reverseUnrolledMap ((x1 : x2 : x3 : _) : cs) acc =
0 commit comments