TU Wien:Funktionale Programmierung VU (Knoop)/Prüfung 2020-06-08 (Lösungsvorschlag)

Aus VoWi
Zur Navigation springen Zur Suche springen

Aufgabe 1 (2+2+10+8 = 22 Punkte = 22%)

[Bearbeiten | Quelltext bearbeiten]

Ja, da das Verhalten im Fall von ungleicher Länge der Zeichenreihen nicht näher definiert wurde.

Hier gibt es unterschiedliche Ansätze:

  1. Panikmodus: Mittels `error :: String -> a` wird die Fehlersituation gemeldet und die Programmauswertung gestopp.
  2. Funktionsspezifischer Auffangwert: -1 als Rückgabewert bei einem Fehler. Dadurch Transparent, nicht Verschleiernd, ...
  3. Fehlerdatentyp: Änderung der Signatur, hin zu `String -> String -> Maybe Int`. Dadurch wird eine Fehlersituation für den Programmierer transparent und kann abgefangen werden.
 abs :: String -> String -> Int
 abs [] [] = 0
 abs (a:as) (b:bs)
   | length as /= length bs = -1
   | a == b = abs as bs
   | otherwise = 1 + abs as bs

Aufgabe 2 (4+4+2+2+2 = 14 Punkte)

[Bearbeiten | Quelltext bearbeiten]
 class Eq a => Ord a where
   (<=) :: a -> a -> Bool -- Relation
   max :: a -> a -> a  -- Operation
   max x -- Protoimplementierung
     | x <= y = y
     | otherwise = x
 instance Eq Bool where
   True == True = True --  ̈Uberschreiben der
   False == False = True -- Proto-Impl. von ==
   _ == _ = False

Typklassen

  1. dienen der Organisation und Verwaltung von ̈Uberladung
  2. sind Sammlungen von Typen, deren Werte typspezifisch, aber mit Funktionen gleichen Namens bearbeitet werden sollen ((==),(>=), (+),(-), etc.).

Überladung

Typklassen dienen der Organisation und Verwaltung von Überladung und erlauben die Wiederverwendung von Funktionen gleichen Namens (z. B.: ==, <, >, >=, +, -, show, ...)

Aufgabe 3 (2+1+(3*2)+5 = 14 Punkte)

[Bearbeiten | Quelltext bearbeiten]

∑k=1..nk2

Direkte Rekursion, genauer: Lineare Rekursion

 f n
   | n == 0 = 0
   | otherwise = f (n-1) + n * n
 f = (\n -> if n == 0 then 0 else f (n-1) + n * n)
 f n = sum [a*a | a <- [1..n]]
 f (2+3)
 (E) ->> if (2+3) == 0 then 0 else f ((2+3)-1) + (2+3) * (2+3)
 (S) ->> if 5 == 0 then 0 else f (5-1) + 5 * 5
 (S) ->> if False then 0 else f (5-1) + 5 * 5
 (S) ->> f (5-1) + 5 * 5
 (E) ->> if (5-1) == 0 then 0 else f ((5-1)-1) + (5-1) * (5-1) + 5 * 5

Aufgabe 4 ((2*4)+8 = 16 Punkte)

[Bearbeiten | Quelltext bearbeiten]
 data Baum a = Blatt a | Baum a a [Baum a]
 type Wald a = [Baum a]
 instance Eq a => Eq (Baum a) where
   (==) (Blatt a) (Blatt b) = a == b
   (==) (Baum a b sub1) (Baum c d sub2) = a == c && b == d && sub1 == sub2
   (==) _ _ = False

Aufgabe 5 (3+3 = 6 Punkte)

[Bearbeiten | Quelltext bearbeiten]
 h :: (a -> b) -> [a] -> [b]

h bildet eine Funktion vom Typ (a -> b) auf eine Funktion vom Typ ([a] -> [b]) ab.

h bildet eine [a]-Wert auf einen [b]-Wert ab, mithilfe einer Funktion vom Typ (a -> b).

Aufgabe 6 (2+2+16+8 = 28 Punkte)

[Bearbeiten | Quelltext bearbeiten]
 type Zeichenreihe = String
 mabs :: [Zeichenreihe] -> Int
 mabs [] = error "Menge ist leer";
 mabs [x] = error "Menge enthält nur eine Zeichenreihe"
 mabs [x,y] = abs x y
 mabs (n:ns) = minimum ([abs n x | x<-ns]++[mabs ns])

Error-Behandlungen im Falle Liste von Zeichenreihe leer ist oder nur eine Zeichenreihe in der Liste ist. Lineare Rekursion wertet den Minimum von der list comprehension aus, wo jede Zeichenreihe mit den folgenden Zeichenreihen verglichen und ihren Abstand berechnet werden. "minimum" liefert von eine Liste [a] -> a den kleinsten Wert.