WS 13/14 ¨Ubungsblatt 8 - Softwaretechnik und Programmiersprachen

Werbung
Lehrstuhl für Softwaretechnik und Programmiersprachen
Jens Bendisposto
Funktionale Programmierung – WS 13/14
Übungsblatt 8
Aufgabe 8.1 (Protokolle)
Eine Bank benutzt Clojure um ihre Konten zu verwalten. Da es verschiedene Arten von Konten
gibt (Girokonten, Tagesgeldkonten, Sparbücher, ...) soll ein Protokoll definiert werden um ein
Konto abstrakt verwenden zu können.
a) Scheiben Sie ein Protokoll PKonto. Das Protokoll folgende Funktionen zur Verfügung stellen
(Parameter sind weggelassen. Sie ms̈sen überlegen, welche Parameter benötigt werden)
• einzahlen: Um einen Betrag auf dem Konto gutzuschreiben. Einzahlungen sind immer
erlaubt (auch wenn das Konto gesperrt wurde)
• abheben?: Soll truthy liefern, falls es möglich ist einen spezifizierten Betrag vom Konto
abzuheben
• abheben: Hebt einen Betrag vom Konto ab
• sperren: Sperrt das Konto
• entsperren: Hebt eine bestehende Sperre auf
b) Definieren Sie eine Datenstruktur für ein Girokonto, das PKonto implementiert. Girtokonten
haben ein Kreditlimit, das nicht überzogen werden darf.
Aufgabe 8.2 (Geldautomat)
Eine Debitkarte kann benutzt werden, um von einem Girokonto einen Betrag abzuheben. Dazu
muss der Benutzer einen vierstelligen PIN eingeben. Wenn der PIN dreimal falsch eingegeben
wird soll das zugehörige Konto gesperrt werden. Zu einem Konto gibt es potentiell mehrere
Debitkarten, die unterschiedliche PINs haben.
a) Implementieren Sie eine Funktion, die eine Debitkarte für ein Girokonto registriert. Bei der
Registrierung wird der PIN festgelegt und im Server der Bank gespeichert. Die Funktion gibt
den PIN zurück.
b) An einem Geldautomaten gibt der Kunde seine Debitkarte ein und legitimiert sich für weitere
Transaktionen. Das ist anders als an einem tatsächlichen Automaten, bei uns muss der Kunde
am Anfang einmal die PIN eingeben und kann dann beliebig viele Aktionen durchführen.
Implementieren Sie eine Funktion, die die Validierung eines Kunden durchführt.
c) Implementieren Sie eine Barabhebung
Aufgabe 8.3 (Software Transactional Memory)
Gegeben sei folgende Funktion, die Transaktionen zwischen zwei Konten implementieren soll.
(defn transfer-money
(when (<= amount
(swap! k1 (fn
(swap! k2 (fn
[k1 k2 amount]
@k1)
[k] (- k amount)))
[k] (+ k amount)))))
Ein Beispielaufruf könnte so aussehen
(def a (atom 1000))
(def b (atom 100))
user=> [@a @b]
[990 110]
user=> (transfer-money b a 1000)
nil
user=> [@a @b]
[990 110]
a) Die Bank hat einen sehr bösen Fehler gemacht. Schreiben Sie einen Test, der den Fehler
aufdeckt. Sie können dazu auch transfer-money so modifizieren, dass der Test einfacher wird.
b) Reparieren Sie das Problem.
c) Schreiben Sie die Funktion so um, dass sie die Protokoll-Funktionen aus den vorhergehenden
Aufgaben benutzt.
d) Erweitern Sie die transfer-money Funktion um Logging. Es soll mit println jede Transaktion
ausgedruckt werden. Achten Sie darauf, dass das log lesbar ist.
Aufgabe 8.4
Gegeben sei die Funktion my-read aus der Vorlesung vom 19.12.2013. Was gibt die Funktion für
folgende Eingaben aus und warum?
(my-read
(my-read
(my-read
(my-read
(my-read
"'(1 2)")
"`(1 2)")
"`~(+ 2 7)")
"`a#")
"`(+ ~@[1 2 3])")
Aufgabe 8.5 (Maybe)
Beweisen Sie, dass Maybe ein Monoid ist. Verwenden Sie dafür folgende Definition:
instance Monoid a => Monoid (Maybe a) where
mempty = Nothing
Nothing `mappend` m = m
m `mappend` Nothing = m
Just m1 `mappend` Just m2 = Just (m1 `mappend` m2)
Aufgabe 8.6 (Either)
Es gibt in Haskell eine Datenstruktur mit dem Namen Either, die so definiert ist:
data Either a b = Left a | Right b
a) Welche Typen haben folgende Ausdrücke?
Left "foo"
Right 1
b) Either hat bezüglich der Typvariablen eine interessante Eigenart. Welche ist das? Überlegen
Sie, wie Sie zum beispiel einen Ausdruck mit dem Typ Either Integer Integer erzeugen
könnten.
c) Können Sie sich vorstellen, wozu man Either benutzt? Vergleichen Sie Either mit Maybe.
Herunterladen