Skip to content

Instantly share code, notes, and snippets.

@bendisposto
Created January 30, 2014 13:35
Show Gist options
  • Save bendisposto/8708411 to your computer and use it in GitHub Desktop.
Save bendisposto/8708411 to your computer and use it in GitHub Desktop.
Lösungsvorschlag Blatt 8
(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