About
- Note
-
- Python supports interfaces on Objects (Classes).
- Dafny supports traits on Objects (Classes) but not datatypes.
- Idris supports interfaces (aka typeclasses) on datatypes.
All of these languages supports:
Higher-Order Functions.
That is, functions are first class, and can be passed around as arguments.
These questions were design to explore Haskell’s use of typeclasses. We will not ask you to do that here. Instead, we will ask that you write solutions using higher-order functions.
See the end of this documents for some hint for Python and Dafny.
Questions
Write a program called
mapwhich takes as input:- A function
fwhich takes a values of typeAand returns a value of typeB; - A list,
xs, of values of typeA;
and returns a list of type
B.- A function
Write a program called
keepwhich takes as input:- A function
fwhich takes a values of typeAand returns a boolean; - A list,
xs, of values of typeA;
and returns a list of values, from
xs, where applyingfreturnstrue.- A function
Write a program called
filterwhich takes as input:- A function
fwhich takes a values of typeAand returns a boolean; - A list,
xs, of values of typeA;
and returns a list of values, from
xs, where applyingfreturnsfalse.As an aside, try write
filterby reusing your implementation fromkeep.- A function
Using your definition of
filter, write a program that returns the same list as it was given.Write a program that combines
mapwithkeepsuch that only the elements which are kept are transformed.Your program must take the following inputs:
- A function
fwhich takes a values of typeAand returns a boolean; - A function
fwhich takes a values of typeAand returns a value of typeB; - A list,
xs, of values of typeA;
Returns a list of values of type
B- try writing the program by hand;
- try writing the program using your earlier definitions of
mapandfilter.
- A function
Write a program that applies a transformation, and returns the results, to all numbers within a given range.
Your program should take as input:
- A function
fwhich performs a transformation on a single integer; - A tuple/pair representing a range with a lower and upper bound in the first and second position;
Your program should return a list of integers;
- try writing the program assuming the range is correct;
- rewrite your program so that invalid ranges cause the program to fail safely;
- A function
Write a program that:
Given the following two functions/methods descriptions:
fthat takes a value of typeAand returns a value of typeB;gthat takes a value of typeBand returns a value of typeC;
Write program
hthat given an element of typeAand functionsfandgas arguments, returns a value of typeC.Using
h, write a program that takes as input:fa function that takes a value of typeAand returns a value of typeB;ga function that takes a value of typeBand returns a value of typeC;- a List of
A
returns a list of values of type
C
Consider the following Python code that finds the largest value in a list.
def memax(xs : list[int]) -> int: return helper(0,xs) def helper(start : int, xs : list[int]) -> int: if len(xs) == 0: return start; head = xs[0] tail = xs[1:] if start >= head: return helper(start,tail) return helper(head, tail)memaxassumes that the largest value must be larger than zero, and useshelperto perform the calculation.Within Python, this forces
memaxto only work on values that can be compared to0.- Rewrite
memaxandhelperso that the programs do not know a priori what the lowest value a datatype can be.- Hint: you will need to extend the arguments for both programs with a function that returns the lowest value.
- Rewrite
memaxandhelperin Dafny (both imperative and functional) and using Idris.
- Rewrite
When using ‘interfaces/typeclasses/traits’ we can layer them so that we can define new functionality from existing generic definitions. This final question uses these to exercise your programming skills.
Python and Idris both have builtin support for capturing the ‘ordering’ of two values.
Within Python, this is the
__lt__interface which enables on to compare values using the binary operator:<. From__lt__we can define other comparison operators such as,<=,>,>=, and==. We can also provide bespome definitions for them.Within Idris, we must define an instance of
Orderingthat informs us how two values compare. Specifically,comparereturns eitherLT,EQ, orGT. We can also define comparison operation using the result ofcompareDafny does not have support for ordering in its standard library.
Regardless, from a single program we can define many more.
Wthin Java the base comparison operator for objects (
compareTo) returns an integer describing how to values compare. Given two values,aandb,compareToreturns:- A negative integer: if
ais less thanb; - Zero: if
ais equal tob; - A positive integer: if
ais greater thanb;
Write programs that, given a
compareTofunction, compute the following comparisons between two values:- Less than
- Greater than
- Less than or equal to
- Greater than or equal to
- Equals to
- maximum
- minimum
- A negative integer: if
Hints
For writing python type hints you will need to import:
from collections.abc import Callable
def apply[A,B](f : Callable[[A],B], x : A) -> B:
return f(a)
def applyBin[A,B](f : Callable[[A,A],B], x : A) -> B:
return f(a,a)Higher-Order functions are specified in Dafny as:
method applyImp<A,B>(f : (A) -> B, x : A) returns (res : B)
{
res := f(x);
}
function applyFn<A,B>(f : A -> B, x : A) : B
{
f(x)
}
method applyBinImp<A,B>(f : (A,A) -> B, x : A) returns (res : B)
{
res := f(x,x);
}
function applyBinFn<A,B>(f : (A,A) -> B, x : A) : B
{
f(x,x)
}