2016-06-18 5 views

Antwort

1

Nein. Bei einem gegebenen Objekt ist es in der Regel nicht möglich, auf andere Objekte zu verweisen. Da Clojure-Maps und -Funktionen unveränderbar sind, müssen Sie zuerst die Funktion und dann die Map erstellen. Es gibt also keine Möglichkeit für die Funktion, auf die Map zuzugreifen, es sei denn, sie wird nach der Erstellung der Map irgendwie übergeben.

jedoch davon aus, dass Sie die Funktion nach dem anderen Wert schaffen kann, können Sie die Funktion ermöglichen, direkt auf den Wert zuzugreifen (aber die enthalten Karte nicht) unter Verwendung eines closure:

((:function 
    (let [value 2 
     function #(str "The value is: " value)] 
    {:value value 
    :function function}))) 
;=> "The value is: 2" 
2

Dies ist eine Variante ist, des Problems der zyklischen Referenzen; lazy definitions allow the construction of these.

Während Clojure Ansatz ist hier nicht ganz so elegant wie die verknüpfte Haskell-Version, promise können Sie einen trägen Verweis auf die Funktion in der Karte und definieren Sie dann die Funktion für den Compiler in einer Umgebung, in der die Karte und Werte sind zugänglich:

(def knot-tying 
    (let[{:keys[val func] :as knot} {:val "foo" :func (promise)} 
     f (fn[](str val "bar"))] 
    (deliver func f) 
    knot)) 

((deref (:func knot-tying))) ;;=>"foobar" 

Oder wenn Sie sich vorziehen, „in der anderen Richtung“ zu binden und mit der Funktion deref verwenden, anstatt zu deref das haben es:

(def knot-tying-2 
    (let[knot (promise) 
     f (fn[] (str (-> knot deref :val) "bar")) 
     tied {:val "foo" :func f}] 
    (deliver knot tied) 
    tied)) 

((:func knot-tying-2)) ;;=>"foobar" 
+1

Aber dann wird der Wert in der Karte an ': f unc' ist keine Funktion; Es ist ein Versprechen. –

+0

Eine Variante hinzugefügt, bei der '' func' 'deref' verwendet und nicht der Benutzer. – Magos

+0

Ah, cool! Daran habe ich nicht gedacht. –

Verwandte Themen