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
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]`.