Created
          January 30, 2014 13:35 
        
      - 
      
 - 
        
Save bendisposto/8708411 to your computer and use it in GitHub Desktop.  
    Lösungsvorschlag Blatt 8
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | (ns muster.core) | |
| (comment | |
| (defprotocol PKonto | |
| (einzahlen [k b]) | |
| (abheben? [k b]) | |
| (abheben [k b]) | |
| (sperren [k]) | |
| (entsperren [k])) | |
| (defrecord Girokonto [stand limit gesperrt pins] | |
| PKonto | |
| (einzahlen [{stand :stand :as k} b] (assoc k :stand (+ stand b))) | |
| (abheben? [{gesperrt :gesperrt stand :stand :as k} b] | |
| (and (not gesperrt) | |
| (<= b (+ stand limit)))) | |
| (abheben [{stand :stand :as k} b] | |
| (if (abheben? k b) | |
| (assoc k :stand (- stand b)) | |
| k)) | |
| (sperren [k] (assoc k :gesperrt true)) | |
| (entsperren [k] (assoc k :gesperrt false))) | |
| ;; Aufgabe 3) | |
| ;; a) | |
| (def a (atom 1000)) | |
| (def b (atom 100)) | |
| (defn transfer-money [k1 k2 amount] | |
| (when (<= amount @k1) | |
| (Thread/sleep 5000) | |
| (swap! k1 (fn [k] (- k amount))) | |
| (swap! k2 (fn [k] (+ k amount))))) | |
| (defn start-thread [f] (.start (Thread. f))) | |
| (do | |
| (start-thread #(transfer-money a b 1000)) | |
| (transfer-money a b 1000) | |
| (not (neg? @a))) | |
| ;; false | |
| ;; b) | |
| (def a (ref 1000)) | |
| (def b (ref 100)) | |
| (defn transfer-money [k1 k2 amount] | |
| (dosync | |
| (when (<= amount @k1) | |
| (Thread/sleep 5000) | |
| (alter k1 (fn [k] (- k amount))) | |
| (alter k2 (fn [k] (+ k amount)))))) | |
| (do | |
| (start-thread #(transfer-money a b 1000)) | |
| (transfer-money a b 1000) | |
| (not (neg? @a))) | |
| ;; true | |
| ;; c) | |
| (defn transfer-money [k1 k2 amount] | |
| (dosync | |
| (when (abheben? @k1 amount) | |
| (alter k1 (fn [k] (abheben k amount))) | |
| (alter k2 (fn [k] (einzahlen k amount)))))) | |
| ;; d) | |
| (def log (agent nil)) | |
| (defn transfer-money [k1 k2 amount] | |
| (dosync | |
| (when (abheben? @k1 amount) | |
| (alter k1 (fn [k] (abheben k amount))) | |
| (alter k2 (fn [k] (einzahlen k amount))) | |
| (send-off log (fn [& ign] (println "Transfered" amount "from" k1 "to" k2)))))) | |
| ;; Aufgabe 4 | |
| (defn my-read [foo] | |
| (let [data (read-string foo) | |
| result (try (eval data) (catch Throwable t (.getMessage t)))] | |
| {:input foo | |
| :read data | |
| :eval result | |
| :data-type (class data) | |
| :eval-type (class result) | |
| })) | |
| (my-read "'(1 2)") | |
| {:input "'(1 2)", | |
| :read (quote (1 2)), | |
| :eval (1 2), | |
| :data-type clojure.lang.Cons, | |
| :eval-type clojure.lang.PersistentList} | |
| (my-read "`(1 2)") | |
| {:input "`(1 2)", | |
| :read (clojure.core/seq (clojure.core/concat (clojure.core/list 1) (clojure.core/list 2))), | |
| :eval (1 2), | |
| :data-type clojure.lang.Cons, | |
| :eval-type clojure.lang.Cons} | |
| (my-read "`~(+ 2 7)") | |
| {:input "`~(+ 2 7)", | |
| :read (+ 2 7), | |
| :eval 9, | |
| :data-type clojure.lang.PersistentList, | |
| :eval-type java.lang.Long} | |
| (my-read "`a#") | |
| {:input "`a#", | |
| :read (quote a__747__auto__), | |
| :eval a__747__auto__, | |
| :data-type clojure.lang.Cons, | |
| :eval-type clojure.lang.Symbol} | |
| {:input "`(+ ~@[1 2 3])", | |
| :read (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/+)) [1 2 3])), | |
| :eval (clojure.core/+ 1 2 3), | |
| :data-type clojure.lang.Cons, | |
| :eval-type clojure.lang.Cons} | |
| ;; Aufgabe 5 | |
| ;; neutrales Element | |
| ;; mempty `mappend` x = x | |
| ;; x `mappend` mempty = x | |
| ;; Nach Definition von mappend trivial. | |
| ;; Assoziativität von mappend | |
| ;; (a mappend b) mappend c = a mappend (b mappend c) | |
| ;; a, b und c sind nicht Nothing. | |
| ;; Wenn z.B. a - Nothing, dann bleibt auf beiden Seiten nur | |
| ;; b mappend c stehen. das ist trivialerweise gleich. Analog b und c. | |
| ;; Sei a = Just x, b = Just y, c = Just z und x,y,z haben den Typ t. t ist Monoid und | |
| ;; mappend auf Typ t bezeichenen wir als mappend2 um die Unterscheidung zu erleichtern | |
| ;; | |
| ;; Einerseits: | |
| ;; (Just x mappend Just y) mappend Just z = Just (x mappend2 y) mappend Just z | |
| ;; = Just ((x mappend2 y) mappend2 z) | |
| ;; = Just (x mappend2 (y mappend2 z)), da t ein Monoid ist | |
| ;; | |
| ;; Andererseits: | |
| ;; Just x mappend (Just y mappend Just z) = Just x mappend Just (y mappend z) | |
| ;; = Just (x mappend2 (y mappend2 z)) | |
| ;; also | |
| ;; (Just x mappend Just y) mappend Just z = Just (x mappend2 (y mappend2 z)) = Just x mappend (Just y mappend Just z) | |
| ;; Aufgabe 6: | |
| ;; a) Left "foo" :: Either [Char] b | |
| ;; Right 1 :: Num b => Either a b | |
| ;; b) Es sind niemals beide Typvariablen festgelegt. Deswegen kann man auch deinen Datenwert | |
| ;; schreiben, der den Typ Either Integer Integer hat. | |
| ;; c) Either kann benutzt werden um wie mit Maybe Berechnungen zu beschreiben die fehlschlagen können | |
| ;; Im Gegensatz zu Maybe kann Either dann einen Fehlerspezifischen Datenwert haben | |
| ;; (oft String um Errormessages zu propagieren) | |
| ) | 
  
    Sign up for free
    to join this conversation on GitHub.
    Already have an account?
    Sign in to comment