2017-05-09 4 views
2

In clojure können Sie die Kartendatenstruktur oder das Schlüsselwort als Funktion verwenden, um die Karte nachzuschlagen.Wie clojure map und keyword eine Funktion sein könnten

(let [m {:foo "bar"}] 
    (get m :foo) ; -> "bar" 
    (:foo m)  ; -> "bar" 
    (m :foo)) ; -> "bar" 

Alle diese Ausdrücke gibt den Wert "bar" zurück. Implementierung, wie ist es möglich, Karte oder das Schlüsselwort als Funktion zu verwenden? Ist das ein Spezialfall, der in einen Clojure-Interpreter eingebaut ist, oder ist es etwas, das ich mit der Sprache neu erstellen könnte? Was passiert eigentlich unter der Haube?

Antwort

4

Es ist alles mit normalem Java unter der Haube gemacht.

Es gibt eine Schnittstelle namens iFn, die alles in Clojure, das als eine Funktion aufgerufen werden soll, implementieren kann. Es liegt an dieser Sache zu entscheiden, was zu tun ist, wenn sie angerufen wird.

  • Schlüsselwörter wählen, um sich selbst in einer Sammlung als das erste Argument übergeben zu sehen.
  • Karten wählen, um das als Schlüssel übergebene Argument in sich selbst nachzuschlagen.
  • Symbole sehen sich auch in einer Sammlung an. Ähnlich wie Keywords.
  • Vars machen einen Funktionsaufruf für jede Funktion, die sie enthalten, mit Hilfe der Argumente, die sie übergeben haben. Und sie verwenden dieselbe Schnittstelle, um das zu tun.
  • +1

    Vars * sind * Funktionen, aber sicher müssen nicht * enthalten * Funktionen. Der Funktionsaufruf ruft vermutlich den Inhalt ab. – Thumbnail

    2

    Nur um Ihnen zu zeigen, wie dies in jeder Sprache möglich ist, die erstklassige Funktionen hat - JavaScript Beispiel unten; Führen Sie es aus, um die Ergebnisse zu sehen!

    const map = x => a => 
     
        a === undefined ? x : a(map(x)) 
     
    
     
    const get = m => a => 
     
        a(m) 
     
    
     
    const accessor = k => m => 
     
        m()[k] 
     
    
     
    // make accessor 
     
    const foo = accessor('foo') 
     
    
     
    // make map 
     
    let m = map({foo: 'bar'}) 
     
    
     
    // test expressions 
     
    // get applied to map and accessor: 
     
    console.log(get (m) (foo)) // bar 
     
    
     
    // accessor applied to map: 
     
    console.log(foo (m))  // bar 
     
    
     
    // map applied to accessor: 
     
    console.log(m (foo))  // bar

    Verwandte Themen