X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=from_lists_to_continuations.mdwn;fp=from_lists_to_continuations.mdwn;h=be7e17f59c88d5797c2373ec5d9d435574221724;hp=c67d5e86c173063a1c7c455b9ada08ea09ad373c;hb=7d27bb2510dd466a8c8135d83b3dc0150ce93bef;hpb=13d59901132acc7a49220d84363227d2f7d1f476 diff --git a/from_lists_to_continuations.mdwn b/from_lists_to_continuations.mdwn index c67d5e86..be7e17f5 100644 --- a/from_lists_to_continuations.mdwn +++ b/from_lists_to_continuations.mdwn @@ -19,9 +19,7 @@ updated version. Expected behavior: -
-t "abSd" ~~> "ababd"
-
+ t "abSd" ~~> "ababd" In linguistic terms, this is a kind of anaphora @@ -32,39 +30,33 @@ This deceptively simple task gives rise to some mind-bending complexity. Note that it matters which 'S' you target first (the position of the * indicates the targeted 'S'): -
-    t "aSbS" 
-        *
-~~> t "aabS" 
-          *
-~~> "aabaab"
-
+ t "aSbS" + * + ~~> t "aabS" + * + ~~> "aabaab" versus -
-    t "aSbS"
-          *
-~~> t "aSbaSb" 
-        *
-~~> t "aabaSb"
-           *
-~~> "aabaaabab"
-
+ t "aSbS" + * + ~~> t "aSbaSb" + * + ~~> t "aabaSb" + * + ~~> "aabaaabab" versus -
-    t "aSbS"
-          *
-~~> t "aSbaSb"
-           *
-~~> t "aSbaaSbab"
-            *
-~~> t "aSbaaaSbaabab"
-             *
-~~> ...
-
+ t "aSbS" + * + ~~> t "aSbaSb" + * + ~~> t "aSbaaSbab" + * + ~~> t "aSbaaaSbaabab" + * + ~~> ... Aparently, this task, as simple as it is, is a form of computation, and the order in which the `'S'`s get evaluated can lead to divergent @@ -80,20 +72,18 @@ zipper `unzipped` and `zipped`; we start with a fully zipped list, and move elements to the zipped part by pulling the zipper down until the entire list has been unzipped (and so the zipped half of the zipper is empty). -
-type 'a list_zipper = ('a list) * ('a list);;
-
-let rec tz (z:char list_zipper) = 
-    match z with (unzipped, []) -> List.rev(unzipped) (* Done! *)
-               | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) 
-               | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *)
-
-# tz ([], ['a'; 'b'; 'S'; 'd']);;
-- : char list = ['a'; 'b'; 'a'; 'b'; 'd']
-
-# tz ([], ['a'; 'S'; 'b'; 'S']);;
-- : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b']
-
+ type 'a list_zipper = ('a list) * ('a list);; + + let rec tz (z:char list_zipper) = + match z with (unzipped, []) -> List.rev(unzipped) (* Done! *) + | (unzipped, 'S'::zipped) -> tz ((List.append unzipped unzipped), zipped) + | (unzipped, target::zipped) -> tz (target::unzipped, zipped);; (* Pull zipper *) + + # tz ([], ['a'; 'b'; 'S'; 'd']);; + - : char list = ['a'; 'b'; 'a'; 'b'; 'd'] + + # tz ([], ['a'; 'S'; 'b'; 'S']);; + - : char list = ['a'; 'a'; 'b'; 'a'; 'a'; 'b'] Note that this implementation enforces the evaluate-leftmost rule. Task completed.