Functional programming · A level · AQA 7517 4.12.1.4, Eduqas A500QS 1.4 · about 25 min
Why every Haskell function takes one argument, partial function application, functools.partial, and composing functions into a sensor pipeline.
[1 mark]In Haskell, mult x y = x * y and triple = mult 3. What is triple 7?
[1 mark]add :: Integer -> Integer -> Integer. What is the type of add 4?
[1 mark]f(x) = x + 2 and g(y) = y³. What is (g ∘ f)(2)?
[1 mark]f(x) = x + 2 and g(y) = y³. What is (f ∘ g)(2)?
[1 mark]f: A → B and g: B → C. What is the type of g ∘ f?
[1 mark]What does this program print?
def compose(g, f):
return lambda x: g(f(x))
double = lambda x: x * 2
less5 = lambda x: x - 5
print(compose(double, less5)(10), compose(less5, double)(10))10 15
compose(double, less5) subtracts 5 first, giving 10; compose(less5, double) doubles first, giving 15.
Build a calibration pipeline for the distance sensor from small curried functions:
- scale(factor) returns a function of one number cm that gives cm * factor.
- offset(amount) returns a function of one number cm that gives cm + amount.
- compose(g, f) returns a function of one value x that gives g(f(x)).
Using only those three, make pipeline: first offset(-2), then scale(10). Apply it to each reading in RAW = (38.0, 51.5, 20.0) and print the results on one line as mm: 360.0 495.0 180.0. Then compose the same two stages in the wrong order and print its results the same way as wrong order: <three numbers>. Round each result to one decimal place. The robot does not move.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
RAW = (38.0, 51.5, 20.0)
def pipeline(cm):
return cm * 10 - 2
print("mm:", pipeline(RAW[0]))The hint students can ask for: Each of scale and offset returns a function that is still waiting for its cm. compose returns a function too. Remember which argument of compose is applied first, then write the wrong order by swapping them.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
RAW = (38.0, 51.5, 20.0)
def scale(factor):
return lambda cm: cm * factor
def offset(amount):
return lambda cm: cm + amount
def compose(g, f):
return lambda x: g(f(x))
pipeline = compose(scale(10), offset(-2))
wrong = compose(offset(-2), scale(10))
print("mm:", " ".join(map(lambda cm: str(round(pipeline(cm), 1)), RAW)))
print("wrong order:", " ".join(map(lambda cm: str(round(wrong(cm), 1)), RAW)))
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.