X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=exercises%2Fassignment1_answers.mdwn;h=49668201ab5a4e8e22ced0e107528189e521883a;hp=280ebf7f90887eb386cf7ba67bb78031c5a79846;hb=7888d341776f23849c60cd82ca816ed13e5bc9c2;hpb=905589079ac294e380072b65523cc5b099e9e22c diff --git a/exercises/assignment1_answers.mdwn b/exercises/assignment1_answers.mdwn index 280ebf7f..49668201 100644 --- a/exercises/assignment1_answers.mdwn +++ b/exercises/assignment1_answers.mdwn @@ -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 [] @@ -62,11 +66,11 @@ 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 @@ -81,23 +85,23 @@ 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]]. @@ -112,22 +116,22 @@ 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 @@ -148,11 +152,11 @@ 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 @@ -178,13 +182,13 @@ 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: @@ -215,7 +219,7 @@ 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]`.