Download as pdf or txt
Download as pdf or txt
You are on page 1of 2

Prof. Dr.

Ralf Hinze TU Kaiserslautern


M.Sc. Sebastian Schloßer
Fachbereich Informatik
AG Programmiersprachen

Functional Programming: Exercise 8


Sheet published: Monday, June 27th
Exercise session: Thursday, June 30th, 12:00

Exercise 8.1. Please take part in the lecture evaluation. If you have not received
an email from the SCI, go to https://vlu.cs.uni-kl.de/teilnahme/ and enter your
*@*.uni-kl.de email address.

Exercise 8.2. Using the free theorem for that type, show that any function

comp :: (b → c) → ((a → b) → (a → c))

must actually be the composition function ◦.

Please do not overlook Exercise 8.3 on the next page.

1
Exercise 8.3 (Skeleton: Evaluator.hs). In the lecture1 , we have developped an evaluator
for the following expression data type:
data Expr
= Lit Integer — a literal
| Expr :+: Expr — addition
| Expr :∗: Expr — multiplication
| Today — some global constant
| Expr :?: Expr — choice
The base implementation
evaluateA :: (Applicative f ) ⇒ Expr → f Integer
supports only expressions without effects (literals, addition and multiplication).
The implementation
evaluateE :: Expr → (Integer → Integer )
is an exact copy of evaluateA, but additionally supports the global today constant.
The implementation
evaluateN :: Expr → [Integer ]
is an exact copy of evaluateA as well, and comes with additional support for choice.
None of those implementations supports expressions that contain the global today constant
and choice at the same time, e.g. Today :?: Lit 42.
We want to implement a function
evaluateEN :: Expr → (Integer → [Integer ])
that supports both the global today constant and choice. The implementation should be
in applicative style such that we can simply copy the first three cases from the evaluateA
implementation. evaluateE uses the Applicative instance for (→) r and evaluateN the one
for [ ], both are predefined in Haskell’s Prelude. We will combine both container types to
a combined one:
type Box r a = r → [a ]
Our Box type synonym combines both effects: The result relies on a global state r and
is nondeterministic ([a ]). Since it is not possible to provide type class instances for type
synonyms, we need to use newtype (or data) to create an actual new type for which we
can instantiate the type class:
newtype Box r a = Box {apply :: r → [a ]}

a) Implement instance Functor (Box r ) and instance Applicative (Box r ). We need


Functor since it is a requirement for Applicative.
b) Implement evaluateEN :: Expr → (Integer → [Integer ]). Note that the return type is
Integer → [Integer ], which is almost Box Integer Integer , but not actually the same
since it is a separate type instead of a type synonym. We do not want that the user of
evaluateEN has to deal with the Box layer.
Implement an internal helper function of type Expr → Box Integer Integer that relies
on the Applicative instance for Box r . In evaluateEN you then can call your helper
function and afterwards just get rid of the Box using apply :: Box r a → (r → [a ]).
1
See in Olat Material/lecture 2021-06-16/solution/InterpreterA.lhs

You might also like