create page
[lambda.git] / exercises / assignment1_answers.mdwn
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]`.