簡體   English   中英

我應該如何將String參數傳遞給clojure.core / apply

[英]How should I pass a String argument to clojure.core/apply

我有以下代碼:

  (condp apply "string argument"
    predicate1? "Result1"
    predicate2? "Result2"
    predicate3? "Result3"
                "Else")

目前, "string argument"在傳遞給apply時被解釋為seq,因此每個字符都成為謂詞的參數:

(apply predicate1? \s \t \r \i \n ...)

一個簡單的解決方案是將參數包裝在一個向量中:

(condp apply ["string argument"] ...)

我不確定這是非常慣用的。 有更好的解決方案嗎?

我認為沒有比直接使用cond更具慣用性的方法,將“字符串參數”綁定到符號並將其傳遞給每個謂詞。 對於閱讀代碼的人來說,其他所有內容都會讓人感到困惑

使用以下輔助宏可以實現額外的魔力:

(defmacro pcond
  "Translates clauses [pred result-expr] to a cond form:

   (cond
    (pred expr) result-expr
    ...)

   A single result-expr can follow the clauses, and it will be appended
   to the cond form under a generated test expression that returns logical 
   true."
  [expr & clauses]
  (let [expr-sym (gensym "expr")
        else-kw (keyword (gensym "else"))
        step (fn [[pred-form clause-form]]
               (if (= else-kw clause-form)
                 [else-kw pred-form]
                 [(list pred-form expr-sym) clause-form]))
        body (->> clauses
                  (partition 2 2 [else-kw])
                  (mapcat step))]
    `(let [~expr-sym ~expr]
       (cond ~@body))))

你可以這樣使用它

(pcond "String argument"
    predicate1 "Result1"
    predicate2 "Result2"
    "Else")

它直接擴展到cond:

(clojure.core/let [expr13755 "String argument"] 
   (clojure.core/cond 
     (predicate1 expr13755) "Result1" 
     (predicate2 expr13755) "Result2" 
     :else13756 "Else"))

您可以使用匿名函數#(%1 %2)來執行您要執行的操作。 IMO它比將condp表達式包裝在一個向量中更好,但無論哪種方式都有效,也不是真正的直截了當。

(condp #(%1 %2) "string argument"
    string? "string"
    map?    "map"
    vector? "vector"
    "something else")

;= Result1

編輯 (從評論中復制)

我不是宏的專家,但我一遍又一遍地聽到的是,如果一個函數會做,你不應該寫一個宏,而condp提供了使用Clojure函數的所有元素。 一種不涉及宏並提高可讀性的方法可以定義一個函數(def apply-pred #(%1 %2))並將其與condp一起condp

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM