-- Fortgeschrittene Funktionale Programmierung, -- LMU, TCS, Wintersemester 2015/16 -- Steffen Jost, Alexander Isenko -- -- Übungsblatt 12. 20.01.2016 -- -- Thema: Database.Persist & Yesod.Persist -- -- Anweisung: -- Bearbeiten Sie ggf. zuerst noch A11-3 und A11-4, -- falls Sie diese noch nicht bearbeitet haben! -- -- Gehen Sie diese Datei durch und bearbeiten Sie -- alle Vorkommen von undefined bzw. die mit -- !!! TODO !!! -- markierten Stellen. Testen Sie Ihre Lösungen mit GHCi! -- {-# LANGUAGE GADTs #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TemplateHaskell, QuasiQuotes #-} import qualified Data.Text as T import Data.Time.Clock (getCurrentTime) import Database.Persist import Database.Persist.Sqlite import Database.Persist.TH import System.Environment (getArgs) import Control.Applicative import Control.Monad import Control.Monad.IO.Class -- Nur für A11-2 benötigt: import Language.Haskell.TH -- A11-1 -- -- Erstellen Sie mit Database.Persist ein simples Kommandozeilen-Tool -- zum Zugriff auf eine Datenbank zur Verwaltung von Hausaufgaben. -- Es soll immer auf die Datenbank im gleichen Verzeichnis zugegriffen werden. -- -- Es gibt 3 Mögliche Verwendungsarten des Tools: -- -- 1) > tool -- -- Legt eine Abgabe für Übung -- von Student mit Matrikelnummer -- in der Datenbank ab. -- Ist der Student unbekannt, so wird er angelegt. -- Die Kombination aus Name und Matrikelnummer muss einzigartig sein. -- -- 2) > tool -- -- Zeigt alle Abgaben zur Übung auf dem Bildschrim an. -- Zu jeder Abgabe wird auch der abgebende Student aufgeführt. -- -- 3) > tool -- -- Zeigt alle Studenten mit diesem Namen an, -- so wie jeweils die Anzahl der im System gespeicherten Abgaben -- zu allen Übungen. -- -- Ein Demo folgt weiter unten. sqliteDB = "demo.sqlite" main :: IO () main = do putStrLn "Hallo zu HuniworX!" args <- getArgs -- !!! TODO !!! return () hilfstext :: IO () hilfstext = do putStrLn "Optionen sind:" putStrLn " 1) Studentenname" putStrLn " 2) Übungsnummer" putStrLn " 3) Studentenname, Matrikel, Übungsnr, Abgabe" putStrLn "Optionen 1 & 2 sind Abfragen; 3 ist Eingabe" maybeRead :: Read a => String -> Maybe a maybeRead (reads -> [(x,"")]) = Just x maybeRead _ = Nothing maybeToInt :: String -> Maybe Int maybeToInt = maybeRead {- DEMO: > ./FFP_U11_Persist Steffen 1234 1 "Etwas gemacht" Hallo zu HuniworX! Migrating: CREATE TABLE "student"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"matrikel" INTEGER NOT NULL,CONSTRAINT "unique_student" UNIQUE ("name","matrikel")) Migrating: CREATE TABLE "abgabe"("id" INTEGER PRIMARY KEY,"ersteller_id" INTEGER NOT NULL REFERENCES "student","ubung" INTEGER NOT NULL,"abgabe" VARCHAR NOT NULL) Abgabe von Steffen für Übung 1 angenommen. > ./FFP_U11_Persist Steffen 6666 1 "Nix gemacht" Hallo zu HuniworX! Abgabe von Steffen für Übung 1 angenommen. > ./FFP_U11_Persist Steffen 6666 2 "Fast nix gemacht" Hallo zu HuniworX! Abgabe von Steffen für Übung 2 angenommen. > ./FFP_U11_Persist Steffen 1234 2 "Schön gemacht." Hallo zu HuniworX! Abgabe von Steffen für Übung 2 angenommen. > ./FFP_U11_Persist Hilde 9999 2 "Vorbildlich gemacht." Hallo zu HuniworX! Abgabe von Hilde für Übung 2 angenommen. > ./FFP_U11_Persist Steffen 1234 3 "Gut gemacht." Hallo zu HuniworX! Abgabe von Steffen für Übung 3 angenommen. > ./FFP_U11_Persist Steffen Hallo zu HuniworX! Steffen 1234 Abgaben: 3 Steffen 6666 Abgaben: 2 > ./FFP_U11_Persist 2 Hallo zu HuniworX! ---- Steffen 6666 für Übung 2 Fast nix gemacht ---- Steffen 1234 für Übung 2 Schön gemacht. ---- Hilde 9999 für Übung 2 Vorbildlich gemacht. > ./FFP_U11_Persist 1 Hallo zu HuniworX! ---- Steffen 1234 für Übung 1 Etwas gemacht ---- Steffen 6666 für Übung 1 Nix gemacht > ./FFP_U11_Persist Fuu 1 Hallo zu HuniworX! Optionen sind: 1) Studentenname 2) Übungsnummer 3) Studentenname, Matrikel, Übungsnr, Abgabe Optionen 1 & 2 sind Abfragen; 3 ist Eingabe > -} -- A11-2 TemplateHaskell -- -- Hier ist etwas zum Knobeln oder Ausprobieren! -- Was machen die folgenden TemplateHaskell Funktionen? -- (zum Ausführen in ghci die Option -XTemplateHaskell nicht vergessen) -- -- a) foobar :: Int -> Int -> ExpQ foobar n i = lamE [pat] rhs where pat = tupP (map varP xs) rhs = varE (xs !! (i - 1)) xs = [ mkName $ "x" ++ show j | j <- [1..n] ] -- b) barfoo :: Int -> ExpQ barfoo n = do ns <- replicateM n (newName "x") lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns) -- c) fuubaz:: Int -> Int -> ExpQ fuubaz n m = do let f = mkName "f" let v i j = mkName $ "x" ++ (show i) ++ (show j) let tupleps = [tupP [varP (v i j) | j <- [1..n]] | i <- [1..m] ] let args = [(foldl appE (varE f) [varE $ v i j | i <- [1..m]]) | j <- [1..n]] lamE ((varP f):tupleps) (tupE args)