summaryrefslogtreecommitdiff
path: root/ws2015
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2015-11-03 10:41:00 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2015-11-03 10:41:00 +0100
commitbbe07c6bd087db4e8319e249380a1823f2b387f1 (patch)
treee345ca037081f24381bc29873f4d2796273e4075 /ws2015
parent593b035e5e40aa3255b364c5eb29a96917a69032 (diff)
downloaduni-bbe07c6bd087db4e8319e249380a1823f2b387f1.tar
uni-bbe07c6bd087db4e8319e249380a1823f2b387f1.tar.gz
uni-bbe07c6bd087db4e8319e249380a1823f2b387f1.tar.bz2
uni-bbe07c6bd087db4e8319e249380a1823f2b387f1.tar.xz
uni-bbe07c6bd087db4e8319e249380a1823f2b387f1.zip
FFP ­ Blatt 03
Diffstat (limited to 'ws2015')
-rw-r--r--ws2015/FFP/blaetter/03/FFP_U03_Funktoren.hs186
1 files changed, 186 insertions, 0 deletions
diff --git a/ws2015/FFP/blaetter/03/FFP_U03_Funktoren.hs b/ws2015/FFP/blaetter/03/FFP_U03_Funktoren.hs
new file mode 100644
index 0000000..51ab9e5
--- /dev/null
+++ b/ws2015/FFP/blaetter/03/FFP_U03_Funktoren.hs
@@ -0,0 +1,186 @@
1-- Fortgeschrittene Funktionale Programmierung,
2-- LMU, TCS, Wintersemester 2015/16
3-- Steffen Jost, Alexander Isenko
4--
5-- Übungsblatt 03 am 3.11.2015
6--
7-- Thema:
8--
9-- Anweisung:
10-- Gehen Sie diese Datei durch und bearbeiten Sie
11-- alle Vorkommen von undefined bzw. die mit -- !!! TODO !!!
12-- markierten Stellen. Testen Sie Ihre Lösungen mit GHCi!
13--
14--
15
16import Data.List (groupBy)
17import Data.Function (on)
18
19-- Bearbeiten Sie zuerst Übungsblatt 02 vollständig!
20
21
22---- A3-1 Funktoren
23--
24-- Machen Sie folgende Datentypen zur einer Instanz der Klasse Functor.
25-- Versuchen Sie dabei, möglichst nicht in die Folien zu schauen!
26-- (Falls Sie doch in die Folien schauen, dann möglichst nur 2-25 und 2-31ff.;
27-- da die Beispiele 2-28 und 2-29 nahezu die komplette Lösung verraten.)
28
29
30-- a)
31data Options a = None | One a | Two a a | Three a a a
32 deriving (Ord, Show)
33
34-- Wenn wir nur die ersten beiden Konstuktoren von "Options" betrachten,
35-- dann haben wir genau den Datentyp "Maybe" aus der Standardbibliothek.
36
37instance Functor Options where
38 fmap _ None = None
39 fmap f (One a) = One (f a)
40 fmap f (Two a b) = Two (f a) (f b)
41 fmap f (Three a b c) = Three (f a) (f b) (f c)
42
43-- Zum Testen:
44testO0 = None
45testO1 = One 4.2
46testO2 = Two 4.2 6.9
47-- Tests auskommentierbar, sobald Functor Instanz definiert:
48testa1 = None == fmap (+2) testO0
49testa2 = Two 8.4 13.8 == fmap (*2) testO2
50
51
52-- b)
53data Tree a = Node a [Tree a]
54 deriving (Eq, Show)
55
56--Hilfsfunktion
57leaf :: a -> Tree a
58leaf x = Node x []
59
60instance Functor Tree where
61 fmap f (Node a xs) = Node (f a) $ map (fmap f) xs
62
63-- Zum Testen:
64testT1 = Node 1 [Node 2 [Node 3 [], leaf 4, Node 5 [leaf 6, leaf 7, leaf 8]], leaf 9, Node 10 [leaf 11]]
65testT2 = Node False [Node True [Node False [],leaf True,Node False [leaf True,leaf False,leaf True]],leaf False,Node True [leaf False]]
66-- Test auskommentierbar, sobald Functor Instanz definiert:
67testb1 = testT2 == (fmap even testT1)
68
69
70
71
72---- A3-2 Funktor (->) a
73--
74-- Die Standardbibliothek definiert eine Funktor-Instanz für den Typ "(->) a".
75-- Wir wollen hier herausfinden, was dies bedeutet:
76--
77-- Der Typ "(->) a" ist ein Typ mit einem ``Loch'',
78-- so wie die Typen "Tree" oder "[ ]" auch.
79-- Die runde Klammer bedeutet lediglich Präfix-Notation anstatt Infix-Notation.
80-- Wenn wir also einen Typ "b" hineingeben wird daraus der Typ (im vertrauten Infix)
81-- a -> b
82-- ganz analog wird aus "Tree" oder "[ ]" zu "Tree b" oder "[b]".
83--
84
85-- a) Welchen konkreten Typ bekommt die Funktion "fmap"
86-- für die Funktor-Instanz von "(->) a"?
87--
88-- Hinweis: Ein Beispiel findet sich auf Folie 2-26.
89-- Oben ist der allgemeine Typ von fmap angegeben.
90-- Unten dann nochmal konkreter für die Listen-Instanz.
91
92{-
93 fmap :: Functor f => (a -> b) -> f a -> f b
94 fmap :: (a -> b) -> (x -> a) -> (x -> b)
95-}
96
97-- b) Die Standardbibliothek enthält bereits eine Funktion des in a) gefundenen Typs!
98-- Wie heisst diese Funktion und was macht sie?
99-- Testen Sie anschließend in GHCI, ob sie die Funktion
100-- tatsächlich mit fmap vertauschen können!
101--
102-- Hinweis: Diese Funktion wird Ihnen in einer Vorlesung über
103-- funktionaler Programmierung mit Sicherheit begegnet sein,
104-- da sie von fundamentaler Bedeutung ist.
105-- (Jedoch sicherlich nicht als Funktor behandelt... ;) )
106
107{-
108 fmap ist hier identisch zu (.)
109 λ ((\a -> (a, a)) `fmap` (\i -> i + 2)) 2
110 (4,4)
111-}
112
113
114
115
116---- A3-3 Unendliche Listen
117--
118-- a) Definieren Sie die unendliche Liste alle Zweierpotenzen: [1,2,4,8,16,32,64,128,256,..]
119
120quadrate :: [Integer]
121quadrate = map (2^) [0..]
122
123-- Zum Testen:
124q1 = take 5 quadrate
125-- > q1
126-- [1,2,4,8,16]
127q2 = quadrate !! 10
128-- > q2
129-- 1024
130
131
132-- b) Definieren Sie eine unendliche Liste, welche alle
133-- erdenklichen Strings aus den Buchstaben ['a','b','c','d'].
134-- Die Reihenfolge ist relativ egal, aber kürzere Strings sollen vor längeren Erscheinen;
135-- d.h. "dd" kommt nach "b", aber vor "abc"
136
137alleVariablen :: [String]
138alleVariablen = seed : alleVariablen' [seed]
139 where
140 seed = ""
141 vars = ['a','b','c','d']
142 alleVariablen' prevs = now ++ alleVariablen' now
143 where
144 now = [v : p | v <- vars, p <- prevs]
145
146-- Zum Testen:
147check l x = (map length . groupBy ((==) `on` length)) (take x l)
148
149-- Beispielimplementierung (muss nicht identisch sein):
150-- > take 30 alleVariablen
151-- [""
152-- ,"a" ,"b" ,"c" ,"d"
153-- ,"aa" ,"ab" ,"ac" ,"ad" ,"ba" ,"bb" ,"bc" ,"bd" ,"ca" ,"cb","cc","cd","da","db","dc","dd"
154-- ,"aaa","aab","aac","aad","aba","abb","abc","abd","aca"]
155--
156-- Prüfe Längen:
157-- > check alleVariablen 30
158-- [1,4,16,9]
159
160
161
162
163-- A3-4 Instanzen
164-- Wer sich mit Klassen und Instanzen noch nicht so sicher fühlt,
165-- sollte zur Übung die automatisch abgeleiteten Instanzdeklaration
166-- für die Datentypdeklarationen in A3-1 von Hand deklarieren;
167-- also z.B.
168-- von "Options" zur Typklassen "Eq"
169-- von "Tree a" zur Typklasse "Ord"
170--
171-- sie müssen oben in den Datentypdeklarationen dann natürlich
172-- die entsprechenden Klassen aus Zeile mit "deriving" herauslöschen
173-- da es ja immer nur _eine_ Instanzdeklaration pro Typ/Klassen-Paar geben darf
174
175instance Eq a => Eq (Options a) where
176 None == None = True
177 None == _ = False
178 One a == One a' = a == a'
179 One _ == _ = False
180 Two a b == Two a' b' = a == a' && b == b'
181 Two _ _ == _ = False
182 Three a b c == Three a' b' c' = a == a' && b == b' && c == c'
183 Three _ _ _ == _ = False
184
185instance Ord a => Ord (Tree a) where
186 compare (Node x xs) (Node x' xs') = compare x x' `mappend` compare xs xs'