BeispielKlausur pfp Haskell Frage (zipWith)

Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.

BeispielKlausur pfp Haskell Frage (zipWith)
ich check leider die Aufgabenstellung nicht ganz
was soll:

Die funktion zipWith wendet eine Funktion auf die jeweils ueber den Index korrespondierenden Elemente zweier Listen an, sofern es die Elemente in beiden Listen gibt. Die Funktion liefert die jeweiligen Ergebnisse als Liste in entsprechender Reihenfolge zurueck.
zipWith :: (a → b → c) → [a] → [ b] → [c]

bedeuten…

wenn ich das richtig verstehe soll aus 2 Listen das 0. element aus a mit dem 0. element aus b $irgendeine Funktion eingehen, was wenn mir die Funktion bekannt waere auch kein stress ist, aber wie schreibe ich sowas allgemein hin?


also ich habs so gelöst:

myzipwith _ _ [] = []
myzipwith _ [] _ = []
myzipwith f (x:xs) (y:ys) = (f x y):myzipwith f xs ys

bsp eingabe:

 myzipwith (\x y -> x+y) [1..10] [11..20]

Ausgabe:

[12,14,16,18,20,22,24,26,28,30]

zipWith f (x:xs) (y:ys) = (f x y) : zipWith f xs ys
und basisfälle halt noch

edit: mist :wink:


is doch keine competition :wink:


zipWith _ [] _ = [] zipWith _ _ [] = [] zipWith f (x:xs) (y:ys) = (f x y):(zipWith f xs ys)
Im Prinzip die selbe Lösung wie sotsouk. Gibts nen Grund, warum du die Funktion _my_zipwith genannt hast?


ah praktisch
danke :slight_smile:


den gibt es, gute alte prolog schule, ich benenne prinzipiell alle meine selbstgeschriebenen Funktion (hab da eine große .hs Datei) mit my***** zwecks der Übersichtlichkeit,

so erkenn ich auf einen Blick ob das mein Werk ist oder ne Lösung die ich irgendwo reinkopiert habe oder obs eben schon mal eine Bibliotheksfunktion mit dem Namen gibt.


wenn ich das jetzt auf die Klausur vom 17.02.2009 anwende

(Die Funktion verbinde erhaelt zwei einstellige Funktionen als Parameter und kombiniert diese zu einer einstelligen Funktion, die als Ergebnis zurückgeliefert wird. Dabei soll die erste Funktion als Bewacher der zweiten dienen, sodass nur dann, wenn der Bewacher für den gegebenen Parameter True zurückliefert, das Ergebnis der zweiten Funktion für diesen Parameter zurückgeliefert wird. Ansonsten soll die Ergebnisfunktion den Parameter unverändert zurückliefern.
verbinde :: (a → Bool) → (a → a) → (a → a)
)

1 verbinde a [] = []
2 verbinde a (x:xs) = if a == 0 then [x+1] ++ xs
3 else [x] ++ verbinde (a-1) xs
4
5 verbinde a b y = if (a y) then (b y)
6 else y

oder stimmt da das else so noch nicht, weil ich hab nicht verbinde :: (a → Bool) → (a → a) → (a → a) sondern (a → Bool) → (a → a) → a → a


verbinde f g x = if f x == True then g x else xoder alternativ mit Wächtern:

verbinde f g x | f x == True = g x | otherwise = x


sollte die aufgabe nicht eigtl mit lambda kalkül gelöst werden:

verbinde g f = (\x → if (g x) then f x else x)


laut aufgabenstellung sind waechter nicht erlaubt sondern nur if else oder mustervergleich :confused: und das == true aendert ja nichts beim if, also hast du genau dasselbe :slight_smile:

aber bekommst auch nicht (a → Bool) → (a → a) → (a → a) sondern (a → Bool) → (a → a) → a → a


[quote=sotsoguk]sollte die aufgabe nicht eigtl mit lambda kalkül gelöst werden[/quote]Sollte, aber der Marc hat in der Besprechung der Klausur erwähnt, dass es gar keinen Unterschied macht, weil Haskell intern das if-then-else-Konstrukt auch auf λ-Funktionen abgebildet.

[quote=mantra]aber bekommst auch nicht (a → Bool) → (a → a) → (a → a) sondern (a → Bool) → (a → a) → a → a[/quote]War das nicht rechtsassoziativ und damit das gleiche? AFAIR wurden stellenweise Klammern der Verständlichkeit halber eingefügt, die so von Haskell nicht ausgegeben würden.


Sowohl der Lambda Ansatz als auch der mit drei Parametern liefern die gleiche Signatur (unabhängig von if oder Wächtern).

Das mit der Rechtsassoziativität stimmt auch, man kann einfach von rechts nach links „durchklammern“:

((a → Bool) → ((a → a) → (a → a)))


hat jemand eine Lösung für die “einfach”-Aufgabe aus der 2008er-Klausur 5.c ?
Ich hab nur 2 Ansätze, die irgendwie ins nirgendwo führen :frowning:

22 einfach (x:xs) (y:ys) | (elem x (y:ys) == True) = einfach xs (entfernen x (y:ys)) 23 | (elem y (x:xs) == True) = einfach (entfernen y (x:xs)) ys 24 einfach2 (x:xs) (y:ys) = [ zusammen as bs | as <- if (elem x (y:ys) == True) then einfach xs (entfernen x (y:ys)), bs <- if (elem y (x:xs) == True) then einfach (entfernen y (x:xs)) ys ]


1 einfuegen a xs | elem a xs = xs
2 | otherwise = (a:xs)
3
4 entfernen a [] = []
5 entfernen a (x:xs) | x == a = xs
6 | otherwise = [x] ++ entfernen a xs
7
8 einfach [] ys = ys
9 einfach (x:xs) ys | elem x ys = einfach xs (entfernen x ys)
10 | otherwise = einfach xs (einfuegen x ys)

die idee war dass ich in der 2. alles losch was in der ersten steht und alles hinzufuege was nicht drinsteht

einfach [1,2,3] [3,4,5]
[2,1,4,5]

wenn man die reihenfolge richtig haben will muss das x:xs halt noch reversed werden (
1 rev [] = []
2 rev (x:xs) = rev xs ++ [x]
)


einfach [] ys = ys
einfach (x:xs) ys | elem x ys = einfach xs (entf x ys) 
				  | True = x:einfach xs ys

Man überprüft alle elemente aus der x liste ob sie in ys sind, sobald alle überprüft sind bedeutet das, dass die restlichen in ys auch nur einfach vorkommen und man hängst sie deshalb im abbruchfall mit dran.


Ich hatte schon in der Übung die Idee diese Aufgabe mit Generatoren zu lösen:

einfach xs ys = xs ++ [y | y <- ys, not (elem y xs)]

Append muss man sich halt dann selbst schreiben, weil ++ in dieser Aufgabe nicht erlaubt war, aber das ist ja aus GLoLoP hinlänglich bekannt.


Dann kriegst du aber auch die Elemente, die in beiden Listen sind, einmal im Ergebnis, weil du xs komplett nimmst. Die willst du aber gar nicht haben.


Ah, sry:

einfach xs ys = [x | x <- xs, not (elem x ys)] ++ [y | y <- ys, not (elem y xs)]