Implement a tail-recursive list map. 1.7.0
authorSiraaj Khandkar <siraaj@khandkar.net>
Sun, 21 Dec 2014 09:37:54 +0000 (04:37 -0500)
committerSiraaj Khandkar <siraaj@khandkar.net>
Sun, 21 Dec 2014 09:37:54 +0000 (04:37 -0500)
src/hope.app.src
src/hope_list.erl
test/hope_list_SUITE.erl

index 64cce31..460fc9e 100644 (file)
@@ -1,7 +1,7 @@
 {application, hope,
  [
   {description, "Higher Order Programming in Erlang"},
 {application, hope,
  [
   {description, "Higher Order Programming in Erlang"},
-  {vsn, "1.6.0"},
+  {vsn, "1.7.0"},
   {registered, []},
   {applications, [
                   kernel,
   {registered, []},
   {applications, [
                   kernel,
index 0d71ece..91ab916 100644 (file)
@@ -6,15 +6,62 @@
 
 -export(
     [ unique_preserve_order/1
 
 -export(
     [ unique_preserve_order/1
+    , map/2
     , map_rev/2
     , map_slow/2
     ]).
 
 
     , map_rev/2
     , map_slow/2
     ]).
 
 
+-define(RECURSION_LIMIT, 1000).
+
+
 -type t(A) ::
     [A].
 
 
 -type t(A) ::
     [A].
 
 
+%% @doc Tail-recursive equivalent of lists:map/2
+%% @end
+-spec map([A], fun((A) -> (B))) ->
+    [B].
+map(Xs, F) ->
+    map(Xs, F, 0).
+
+-spec map([A], fun((A) -> (B)), non_neg_integer()) ->
+    [B].
+map([], _, _) ->
+    [];
+map([X1], F, _) ->
+    Y1 = F(X1),
+    [Y1];
+map([X1, X2], F, _) ->
+    Y1 = F(X1),
+    Y2 = F(X2),
+    [Y1, Y2];
+map([X1, X2, X3], F, _) ->
+    Y1 = F(X1),
+    Y2 = F(X2),
+    Y3 = F(X3),
+    [Y1, Y2, Y3];
+map([X1, X2, X3, X4], F, _) ->
+    Y1 = F(X1),
+    Y2 = F(X2),
+    Y3 = F(X3),
+    Y4 = F(X4),
+    [Y1, Y2, Y3, Y4];
+map([X1, X2, X3, X4, X5 | Xs], F, Count) ->
+    Y1 = F(X1),
+    Y2 = F(X2),
+    Y3 = F(X3),
+    Y4 = F(X4),
+    Y5 = F(X5),
+    Ys =
+        case Count > ?RECURSION_LIMIT
+        of  true  -> map_slow(Xs, F)
+        ;   false -> map     (Xs, F, Count + 1)
+        end,
+    [Y1, Y2, Y3, Y4, Y5 | Ys].
+
+
 %% @doc lists:reverse(map_rev(L, F))
 %% @end
 -spec map_slow([A], fun((A) -> (B))) ->
 %% @doc lists:reverse(map_rev(L, F))
 %% @end
 -spec map_slow([A], fun((A) -> (B))) ->
index 38d406a..6967458 100644 (file)
@@ -14,6 +14,7 @@
     , t_hope_list_specs/1
     , t_map_rev/1
     , t_map_slow/1
     , t_hope_list_specs/1
     , t_map_rev/1
     , t_map_slow/1
+    , t_map/1
     ]).
 
 
     ]).
 
 
@@ -35,6 +36,7 @@ groups() ->
         , t_hope_list_specs
         , t_map_rev
         , t_map_slow
         , t_hope_list_specs
         , t_map_rev
         , t_map_slow
+        , t_map
         ],
     Properties = [parallel],
     [{?GROUP, Properties, Tests}].
         ],
     Properties = [parallel],
     [{?GROUP, Properties, Tests}].
@@ -54,6 +56,13 @@ t_map_slow(_Cfg) ->
     [2, 3, 4] = hope_list:map_slow([1, 2, 3], F),
     []        = hope_list:map_slow([], F).
 
     [2, 3, 4] = hope_list:map_slow([1, 2, 3], F),
     []        = hope_list:map_slow([], F).
 
+t_map(_Cfg) ->
+    F = fun (N) -> N + 1 end,
+    Xs = lists:seq(1, 5010),
+    Ys = lists:map(F, Xs),
+    Ys = hope_list:map(Xs, F),
+    [] = hope_list:map([], F).
+
 t_unique_preserve_order(_Cfg) ->
     ?PROPTEST(prop_unique_preserve_order).
 
 t_unique_preserve_order(_Cfg) ->
     ?PROPTEST(prop_unique_preserve_order).
 
This page took 0.025354 seconds and 4 git commands to generate.