Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: c3d2/ta-haskell-yesod
base: 4a831da1e7
...
head fork: c3d2/ta-haskell-yesod
compare: 3784d5df64
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on Aug 29, 2012
@maloi maloi TH cb7e8d6
@maloi maloi TH fibs 3784d5d
Showing with 138 additions and 0 deletions.
  1. +11 −0 Fibs.hs
  2. +8 −0 Main.hs
  3. BIN  architecture.png
  4. +119 −0 index.html
View
11 Fibs.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Fibs where
+import Language.Haskell.TH
+import Language.Haskell.TH.Syntax
+
+fibs :: [Integer]
+fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
+
+fibQ :: Int -> Q Exp
+fibQ n = [| $( lift $ fibs !! n) |]
View
8 Main.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Main where
+import Language.Haskell.TH
+import Fibs
+
+
+main = print $(fibQ 100000)
View
BIN  architecture.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
119 index.html
@@ -1019,6 +1019,125 @@
<!--
* Template Haskell (maloi) (20min)
-->
+
+<div class="slide">
+ <h1>Template Haskell - Motivation</h1>
+ <ul class="incremental">
+<li><strong>Bedingte Kompilierung</strong> - Versionen fuer unterschiedliche Betriebssysteme, Debuginformationen</li>
+<li><strong>Programm Reifikation</strong> - (Introspektion) Eigene Struktur erkennen. Programm kann sich selbst analysieren, veraendern oder neue Programme erstellen</li>
+<li><strong>Algorithmische Programmkonstruktion</strong> - Lange Programme durch kurzen Algorithmus konstruieren. TH ubernimmt Konstruktion zu Compilezeit</li>
+<li><strong>Erweiterung der Abstraktionsmechanismen</strong> - Nutzer kann z.B. eigene Compilererweiterungen schreiben, ohne dass diese im Compiler integriert sein muessen</li>
+<li><strong>Optimierungen</strong> - Unrolling (Verlagerung von Rekursion von Laufzeit in Compilezeit</li>
+ </ul>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Aufbau</h1>
+ <h3><img src="architecture.png" /></h3>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Programmcode als Abstrakte Datentypen</h1>
+ <p>AST wird mit Hilfe einfacher ADTs dargestellt</p>
+ <p>Im untersten Layer existieren Exp, Pat, Dec, Typ</p>
+ <p>Will man ein Tupel-Ausdruck erzeugen benutzt man den Konstruktor TupE</p>
+ <p>LamE fuer Lambda Ausdruecke</p>
+ <ul>
+ <li>E fuer Ausdruecke</li>
+ <li>P fuer Patterns</li>
+ <li>D fuer Deklarationen</li>
+ <li>T fuer Typdefinitionen</li>
+ </ul>
+ <p>TupE ist nicht gleich TupP (Tupel innerhalb eines Patterns</p>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Programmcode als Abstrakte Datentypen</h1>
+
+ <li style="list-style-type: none;">
+ <pre class="sh_haskell">LamE [ TupP [ VarP $ mkName "x",
+ VarP $ mkName "y" ]
+ ]
+ ( TupE [ VarE $ mkName "x",
+ VarE $ mkName "y"]
+ )</pre>
+ </li>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Probleme</h1>
+
+ <li style="list-style-type: none;">
+ <pre class="sh_haskell">InfixE (Just (LitE (IntegerL 1))) (VarE $ mkName "+") (Just (LitE (CharL 'a')))</pre>
+ <p>Ergibt 1+'a' aber es gibt kein Typfehler</p>
+ </li>
+ <li style="list-style-type: none;">
+ <pre class="sh_haskell">LamE [VarP mkName "x"](VarE mkName "notInScope")</pre>
+ <p>Nach Umwandlung in Haskell Code erfolgt eine Compilierung nur wenn es auch eine FUnktion notInScope im Scope gibt</p>
+ </li>
+ <li style="list-style-type: none;">
+ <pre class="sh_haskell"> cross :: Exp -> Exp -> Exp
+ cross f g
+ = LamE [TupP [ VarP $ mkName "x",
+ VarP $ mkName "y"
+ ]
+ ] $
+ TupE [ AppE f (VarE $ mkName "x"),
+ AppE g (VarE $ mkName "y")
+ ]</pre>
+ <p>Erwartet zwei Ausdruecke f und g vom Typ Exp um einen Lambdaausdruck zu erstellen</p>
+ <p>Uebergibt man nun die Ausdruecke VarE $ mkName "x" und VarE $ mkName "y" als Parameter an die Funktion cross, meldet der Compiler zunaechst keinen Fehler.</p>
+ <p>Nach Umwandlung in Haskell Code kommt jedoch folgender Fehler:</p>
+ <li style="list-style-type: none;">
+ <pre class="sh_haskell">Occurs check: cannot construct the infinite type: t = t -> t1
+Probable cause: `x' is applied to too many arguments
+In the expression: x x
+In the expression: (x x, y y)</pre>
+ </li>
+</div>
+
+<div class="slide">
+ <h1>Template Haskell - Die Q-Monade</h1>
+ <p>Erweiterung der IO Monade um einige Features</p>
+ <p>WIchtigstes Feature: Globaler Namenspeicher - Erzeugung von Namen, so dass es zu keinen Namenskonflikten kommen kann</p>
+ <pre class="sh_haskell">newName :: String -> Q Name -- erzeugt einzigartige Namen</pre>
+ <pre class="sh_haskell"> cross :: ExpQ -> ExpQ -> ExpQ
+ cross f g = do
+ x <- newName "x"
+ y <- newName "y"
+ ft <- f
+ gt <- g
+ return (LamE [ TupP [ VarP x,
+ VarP y
+ ]
+ ]
+ ( TupE [ AppE ft (VarE x),
+ AppE gt (VarE y)
+ ]
+ )
+ )</pre>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Splices</h1>
+ <pre class="sh_haskell">> let f = LamE [VarP $ mkName "x"] (VarE $ mkName "x")
+
+> :t f
+f :: Exp
+
+> let g = $(return f)
+
+> :t g
+g :: t -> t
+
+> g 42
+42</pre>
+</div>
+<div class="slide">
+ <h1>Template Haskell - Quasiquoting</h1>
+ <pre class="sh_haskell"> data Expr = IntExpr Integer
+ | BinopExpr (Integer -> Integer -> Integer) Expr Expr
+ deriving(Show)</pre>
+ <pre class="sh_haskell">> [expr|1 + 3 + 5|]
+ BinopExpr AddOp (BinopExpr AddOp (IntExpr 1) (IntExpr 3)) (IntExpr 5)</pre>
+ <pre class="sh_haskell"> cross :: ExpQ -> ExpQ -> ExpQ
+ cross f g = [| \ (x,y) -> ($f x, $g y) |]</pre>
+</div>
<div class="slide">
<h1>Profiling</h1>
<p class="incremental">Beispiel aus Real World Haskell, Chapter 25:</p>

No commit comments for this range

Something went wrong with that request. Please try again.