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:
K
C′
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
K
1
,
not
K
2
.)
Try this on the μ
(Y
) combinator,
where the μ
combinator is
given by
λGx.[λy.yy]
(λRz.G(RR)z)x.
fall-2024