Typos fixed 2013-10-09.
| This is a course page of David Casperson You are here: home → Semesters → Fall 2013 → CPSC 370 |
|
Typos fixed 2013-10-09. Updated 2013-12-02.
can be found here .
How many of these are fair and interesting?
fun q f a b = f(a,b) ;
do? What is its type?
uncurry3 that
takes a twice-Curried (“three argument”) function and
returns an ordinary ternary (three argument) function.
andalso
and orelse are syntactic sugar. Be careful!
Using the relations
write a Scheme program to calculate e to the x. Compare your
results with the builtin exp function.
(Note that
, or
.)
The following questions ask you to code various Standard ML list functions. Please code your solutions from scratch.
concat function that takes a list of lists
to a list. By example, concat
[[3,1,2],[],[],[3],[1]] is [3,1,2,3,1].
For this question, you may use the builtin
function @, which appends one list to another.
exists function that takes a predicate (a
function whose return type is bool) and (curried) a
list and returns true or false depending
on whether any element of the list satisfies the predicate.
all function that works
like any, except that it returns true
or false depending
on whether all elements of the list satisfy the predicate.
tabulate function.
This is a two‐argument function whose first argument is an
integer that equals the length of the list returned, and whose
second argument is a function. This latter function takes a
zero-indexed position, and returns the corresponding element of
the answer.tabulate (3,Int.toString)
["0","1","2"]
take function
in Scheme.
tabulate in
in Standard ML)
in a tail-recursive way.
val exists: α array → bool
which works analogously to all
val take: int × α array → α array
which works similarly to drop, but returns the
first n elements.
val map: (α → β) → (α array →
β array)
which applies a given function to every element of a given
persistent array. Estimate the time complexity of
your map function.
rev to be tail-recursive.
Hint:
The easiest way to unravel this is to un-apply
η-reduction.
That is, replace
S(S(KS)(S(KK)S))(KK)
with
λ
f.S(S(KS)(S(KK)S))(KK)(f),
apply the combinator rules that you can. Then apply this
trick again a couple of times to the body of the simplified
λ f.S(S(KS)(S(KK)S))(KK)(f)
expression.
If you have done things correctly, you should end up with short λ-expression of three variables.
λNfx.Nf(fx) into an
SKI combinator.
sublists(3,[1,2,3,4,5]) should produce
[[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5],
[1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]
One approach to the problem above is to first list the sublists that involve the first element, then those that don’t. The structure is shown below.
| 1 | >sublist(2,[2,3,4,5]) | >||
| sublist(3,[2,3,4,5]) | |||
This suggest code of the form
(map ??? recursive_call) @
(recursive_call)
An inefficiency here is that the first list gets generated first by the recursive call, then again, by the map function, then a third time by the append.
We can remove the need for
the map call by generalizing sublist.
Define
sublistB f
(k, list)
to produce the same thing as
map f (sublist
(k, list)) , but do so in a way
that sublistB calls itself and does not call map.
Using a let-block, code sublist so
that sublist (k, list)
calls sublistB I (k, list).
Define
sublistC f
(k, list) acc
to produce the same thing as
sublistB f (k, list)
@ acc, but do so in a way
that sublistC calls itself.
sublist(?Small,+K,?Big)
that holds when Small is a K element
sublist of Big.
portrayAppLeft and
portrayAppRight so that λ-terms display nicely.
etaReduces(+A,-B) that succeeds
when B is the η-reduction of A, where A and B are coded as in
class.
S,
K, and
I combinators.
Here is a sketch of a strategy:
KC′
where
C converts to C′,
provided that C is free of x.
I.
S(A′)(B′)
where
λx.A converts to A′
and
λx.B converts to B′.
(Caution: when removing λs you may need to lower
the index in bound variables. For instance when converting
λxyz.x (aka
λλλ.2),
you recursively encounter the problem
λ.2, which should translate to
K1,
not
K2.)
Try this on the μ
(Y) combinator,
where the μ combinator is
given by
λGx.[λy.yy]
(λRz.G(RR)z)x.
fall-2024