author jim Tue, 10 Feb 2015 02:27:00 +0000 (21:27 -0500) committer Linux User Tue, 10 Feb 2015 02:27:00 +0000 (21:27 -0500)

index 280ebf7..4966820 100644 (file)
@@ -17,6 +17,8 @@
end
in empty?

+    The second `case` clause could also just be `_ then 'false`.
+
3.  Define a function `tail` that expects a sequence of values as an argument (doesn't matter what type of values), and returns that sequence with the first element (if any) stripped away. (Applying `tail` to the empty sequence `[]` can just give us back the empty sequence.)

let
@@ -51,6 +53,8 @@
tail xs = drop (1, xs)
in ...

+    That uses [[the shorthand explained here|topics/week1_kapulet_advanced#funct-declarations]], which I will continue to use below.
+
5.  Define a function `take` that expects two arguments, in the same form as `drop`, but works like this instead:

take (0, [10, 20, 30])  # evaluates to []
<!-- -->

letrec
-          take match lambda (n, xs). case (n, xs) of
-                                       (0, _)        then [];
-                                       (_, [])       then [];
-                                       (_, x' & xs') then x' & take (n-1, xs')
-                                     end
+          take (n, xs) = case (n, xs) of
+                           (0, _)        then [];
+                           (_, [])       then [];
+                           (_, x' & xs') then x' & take (n-1, xs')
+                         end
in take

<!-- -->

letrec
-          split match lambda (n, xs). case (n, xs) of
-                                       (0, _)        then ([], xs);
-                                       (_, [])       then ([], []);
-                                       (_, x' & xs') then let
-                                                            (ys, zs) match split (n-1, xs')
-                                                          in (x' & ys, zs)
-                                     end
+          split (n, xs) = case (n, xs) of
+                           (0, _)        then ([], xs);
+                           (_, [])       then ([], []);
+                           (_, x' & xs') then let
+                                                (ys, zs) match split (n-1, xs')
+                                              in (x' & ys, zs)
+                          end
in split

7.  Write a function `filter` that expects two arguments. The second argument will be a sequence `xs` with elements of some type *t*, for example numbers. The first argument will be a function `p` that itself expects arguments of type *t* and returns `'true` or `'false`. What `filter` should return is a sequence that contains exactly those members of `xs` for which `p` returned `'true`.

letrec
-          filter match lambda (p, xs). case xs of
-                                         [] then [];
-                                         x' & xs' when p x' then x' & filter (p, xs');
-                                         _  & xs'           then      filter (p, xs')
-                                       end
+          filter (p, xs) = case xs of
+                             [] then [];
+                             x' & xs' when p x' then x' & filter (p, xs');
+                             _  & xs'           then      filter (p, xs')
+                           end
in filter

The above solution uses [[pattern guards|/topics/week1_kapulet_advanced#guards]].
<!-- -->

letrec
-          partition match lambda (p, xs). case xs of
-                                            []       then ([], []);
-                                            x' & xs' then let
-                                                            (ys, zs) match partition (p, xs')
-                                                          in if p x' then (x' & ys, zs) else (ys, x' & zs)
-                                          end
+          partition (p, xs) = case xs of
+                                []       then ([], []);
+                                x' & xs' then let
+                                                (ys, zs) match partition (p, xs')
+                                              in if p x' then (x' & ys, zs) else (ys, x' & zs)
+                              end
in partition

9.  Write a function `double` that expects one argument which is a sequence of numbers, and returns a sequence of the same length with the corresponding elements each being twice the value of the original element.

letrec
-          double match lambda xs. case xs of
-                                    []       then [];
-                                    x' & xs' then (2*x') & double xs'
-                                  end
+          double xs = case xs of
+                        []       then [];
+                        x' & xs' then (2*x') & double xs'
+                      end
in double

<!-- -->

letrec
-          map2 match lambda (f, xs, ys). case (xs, ys) of
-                                      ([], _)              then [];
-                                      (_, [])              then [];
-                                      (x' & xs', y' & ys') then (f x' y') & map2 (f, xs', ys')
-                                    end
+          map2 (f, xs, ys) = case (xs, ys) of
+                               ([], _)              then [];
+                               (_, [])              then [];
+                               (x' & xs', y' & ys') then (f x' y') & map2 (f, xs', ys')
+                             end
in map2

Then `unmap2 (g, [z1, z2, z3])` should evaluate to `([x1, x2, x3], [y1, y2, y3])`.

letrec
-          unmap2 match lambda (g, zs). case zs of
-                                         []       then ([], []);
-                                         z' & zs' then let
-                                                         (x, y)   match g z';
-                                                         (xs, ys) match unmap2 (g, zs')
-                                                       in (x & xs, y & ys)
-                                       end
+          unmap2 (g, zs) = case zs of
+                             []       then ([], []);
+                             z' & zs' then let
+                                             (x, y)   match g z';
+                                             (xs, ys) match unmap2 (g, zs')
+                                           in (x & xs, y & ys)
+                           end
in unmap2

*   Write a function `takewhile` that expects a `p` argument like `filter`, and also a sequence. The result should behave like this:
end
in dropwhile

-    Unlike the previous solution, this one uses [[pattern guards|/topics/week1_kapulet_advanced#guards]], merely for variety. (In this solution the last two case clauses could also be replaced by the single clause `_ then xs`.)
+    Unlike the previous solution, this one uses [[pattern guards|/topics/week1_kapulet_advanced#guards]], merely for variety. (In this solution the last two `case` clauses could also be replaced by the single clause `_ then xs`.)

*   Write a function `reverse` that returns the reverse of a sequence. Thus, `reverse [1, 2, 3, 4]` should evaluate to `[4, 3, 2, 1]`.