Sieve und Vis-Output in den Text rein.
authorJoachim Breitner <mail@joachim-breitner.de>
Wed, 5 Sep 2012 10:25:30 +0000 (10:25 +0000)
committerJoachim Breitner <mail@joachim-breitner.de>
Wed, 5 Sep 2012 10:25:30 +0000 (10:25 +0000)
HaskellBytes.tex
Sieve.hs [new file with mode: 0644]

index 3e2b419..f7218cf 100644 (file)
@@ -221,7 +221,7 @@ An dieser Stelle sollte klar sein dass sich der eingebaute \li-String--Datentyp
 
 Wenden wir uns nun der nächsten Art von Closures zu, nämlich Funktionen. Weil es hier interpretiert recht anders als kompiliert funktioniert lasse ich folgendes Programm laufen:
 
-\lstinputlisting[style=haskell]{FunClosures.hs}\mylabel{Haskell}
+\inputhaskell{FunClosures.hs}
 was zu folgender Ausgabe führt:
 \begin{shell}
 $ ghc --make FunClosures.hs -O && ./FunClosures  1 2 3
@@ -258,6 +258,10 @@ l2 = map negate l
 \end{haskell}
 anzuschauen und zu beobachten, wie die Auswertung der einen Liste die andere beeinflusst.
 
+\begin{center}
+\includegraphics[width=0.4\linewidth]{vis-output1.pdf}
+\end{center}
+
 Zum Vergleich nehmen wir diese Funktion für unendliche Listen, die -- semantisch -- das gleiche macht:
 \begin{haskell}
 infList2 f x = let l = f x : l in l
@@ -266,6 +270,9 @@ und untersuchen \li-l3 = infList2 (+19) (23::Int)- mit \li-:view-. Tatsächlich
 
 Leider sind solche selbstbezüglichen Datenstrukturen fragil, wenn man sie „ändern“ will; schon ein einfaches \li-map negate l2- zerstört die Struktur, wie man hier gut sehen kann.
 
+\begin{center}
+\includegraphics[width=0.2\linewidth]{vis-output2.pdf}
+\end{center}
 
 An dieser Stelle will ich wieder auf das zweite Beispiel vom Anfang zurückkommen. Jetzt können wir mit \li!ghc-vis! dem Stack Overflow auf den Grund gehen: 
 \begin{ghci}
@@ -349,6 +356,16 @@ Was aber am häufigsten mit so einem Closure passiert ist, dass er ausgeführt w
 \end{center}
 
 
+\section{Das Primzahlensieb}
+
+Falls es die Zeit erlaubt will ich noch einem weiteren Programm bei der Ausführung zuschauen, nämlich der bekannten, sehr eleganten Definition der Primzahlen:
+\inputhaskell{Sieve.hs}
+Hier erkennt man schön die immer länger werdende Liste von Thunks, die jeweils für eine Primzahl deren vielfache aus der Liste entfernt:
+
+\begin{center}
+\includegraphics[width=0.2\linewidth]{vis-output-sieve.pdf}
+\end{center}
+
 \section{Fazit}
 
 Damit bin ich am Ende meines Vortrages. Wir haben uns die Mühe gemacht, all die vielen komfortablen Abstraktionsschichten, die uns Haskell bereitstellt, beiseite zu schieben und haben einen ungetrübten Blick auf den Speicher geworfen. Wir haben gesehen dass die Daten doch einigermaßen übersichtlich und effizient gespeichert werden. Wir haben auch gesehen, warum \li-Strings-s so teuer sind und wie man eine unendlich lange Liste in wenigen Bytes speichert. Ich hoffe, dass euch dieser Vortrag hilft besser zu verstehen, warum eure Haskell-Programme so laufen wie sie laufen, und zu wissen, wie ihr sie besser laufen lassen könnt.
diff --git a/Sieve.hs b/Sieve.hs
new file mode 100644 (file)
index 0000000..954acf1
--- /dev/null
+++ b/Sieve.hs
@@ -0,0 +1,6 @@
+module Sieve where
+
+primes :: [Integer]
+primes = sieve [2..]
+  where
+    sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]