Functional programming · A level · AQA 7517 4.12.1.2, Eduqas A500QS 1.4 · about 20 min
Functions as values in variables, lists and dictionaries, passed as arguments and returned as results, lambdas, closures and a robot command table.
[1 mark]Which of these can a first-class object do?
Tick every answer that is true.
[1 mark]What makes a function higher-order?
[1 mark]What does this program print?
def apply_twice(f, x):
return f(f(x))
print(apply_twice(lambda n: n * 3, 2))18
The lambda triples: 2 becomes 6, then 6 becomes 18.
[1 mark]What does this program print?
def make_adder(n):
return lambda x: x + n
fs = [make_adder(5), make_adder(-1), abs]
print([f(-3) for f in fs])[2, -4, 3]
make_adder returns a new function that remembers n. The list holds three functions, and each is applied to -3.
[1 mark]double is a function. What does the line f = double do?
[1 mark]A Haskell function has type applyTwice :: (a -> a) -> a -> a. What is its first argument?
Drive a route from a table of functions, with no if or elif anywhere in the program: the table does the choosing.
- drive_forward(cm) drives forward cm centimetres at speed 50, and drive_back(cm) drives backward cm centimetres at speed 50.
- make_turn(direction) takes "left" or "right" and returns a new function of one parameter, degrees, that turns that way by degrees at speed 30.
- ACTIONS is a dictionary from the letters "F", "B", "L" and "R" to drive_forward, drive_back, make_turn("left") and make_turn("right").
- run_route(actions, route) takes a table like ACTIONS and a list of commands, each a letter followed by a whole number such as "F25". For each command in order it prints the letter and the number separated by a space, such as F 25, and applies the letter's function to the number.
Call run_route(ACTIONS, ["F25", "R90", "F20", "L90", "B10"]).
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def run_route(route):
for command in route:
letter = command[0]
amount = int(command[1:])
if letter == "F":
forward(50, distance=amount)
elif letter == "R":
turn_right(30, angle=amount)
run_route(["F25", "R90", "F20", "L90", "B10"])The hint students can ask for: Start with the table: each letter needs a function of one number. make_turn has to hand back a function it has just made, so decide which robot command that inner function calls without asking with an if; a dictionary lookup can choose it. run_route then only looks up and applies.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
def drive_forward(cm):
forward(50, distance=cm)
def drive_back(cm):
backward(50, distance=cm)
def make_turn(direction):
turn = {"left": turn_left, "right": turn_right}[direction]
def do_turn(degrees):
turn(30, angle=degrees)
return do_turn
ACTIONS = {"F": drive_forward, "B": drive_back, "L": make_turn("left"), "R": make_turn("right")}
def run_route(actions, route):
for command in route:
letter, amount = command[0], int(command[1:])
print(letter, amount)
actions[letter](amount)
run_route(ACTIONS, ["F25", "R90", "F20", "L90", "B10"])
Any program that meets the task's checks is marked correct in the simulator; this is one way, not the only way.