【问题标题】:Multiple namespaces; trying to call method in one, passing output to another method within 3rd method多个命名空间;尝试在一个方法中调用方法,将输出传递给第三种方法中的另一个方法
【发布时间】:2016-10-19 14:13:36
【问题描述】:

我有一个实现这样的多方法的命名空间:

(ns a)
(defmulti funca (fn [system data] system))
(defmethod funca :add-z 
  [system data] 
  (conj data {:z 26}))

我有第二个命名空间实现不同的多方法:

(ns b)
(defmulti funcb (fn [system data new-element] system))
(defmethod funcb :add-element
  [system data new-element]
  (conj data new-element))

我将第三个命名空间定义为

(ns c
  (:require [a :refer [funca]]
            [b :refer [funcb]]))

我想在命名空间 c 中创建一个方法,我可以调用它,例如

(funcc (funca :add-z {:a 1 :b 2 :c 3})
       (funcb :add-element {:y 25}))

这应该获取(funca :add-z {:a 1 :b 2 :c 3})(即{:a 1 :b 2 :c 3 :z 26})的结果并将该结果用作(funcb :add-y-and-count-elements {:y 25}) 的输入,然后返回结果{:a 1 :b 2 :c 3 :y 25 :z 26}

在尝试定义 funcc 时,我正在尝试类似

(ns c
  (:require [a :refer [funca]]
            [b :refer [funcb]]))
(defn funcc [funca funcb]
  (partial funcb funca))

(defn funcc [funca funcb]
  (funcb (funca)))

(defn funcc [funca funcb]
  (-> funca
      funcb))

但是当在 REPL 中运行其中任何一个并调用 funcc 时,我得到了

传递给 b/eval19367/fn 的 args (2) 数量错误

定义funcc的正确语法是什么,这样它就可以将第一个参数的输出作为传递给它的第二个参数的输入,然后返回结果?

【问题讨论】:

    标签: methods clojure namespaces


    【解决方案1】:

    这应该采用(funca :add-z {:a 1 :b 2 :c 3}) 的结果(即{:a 1 :b 2 :c 3 :z 26}) 并将该结果用作(funcb :add-y-and-count-elements {:y 25}) 的输入,然后返回结果{:a 1 :b 2 :c 3 :y 25 :z 26}

    根据此描述,您的funcc 实际上只接受一个参数(调用funca 的结果),因此它应该这样定义:

    (defn funcc [data]
      (funcb :add-element data {:y 25}))
    

    然后调用它:

    (funcc (funca :add-z {:a 1 :b 2 :c 3}))
    

    如果您总是想调用funcc 并将funca 的结果应用于add-z 并带有一些数据,您可以将其更改为:

    (defn funcc [data]
      (let [result-from-funca (funca :add-z data)]
        (funcb :add-element result-from-funca {:y 25})))
    

    然后调用它:

    (funcc {:a 1 :b 2 :c 3})
    

    【讨论】:

      【解决方案2】:

      使用 as-> 宏

      (as-> {:a 1 :b 2 :c 3} data
         (funca :add-z data)
         (funcb :add-element data {:y 25}))
      

      如果funcafuncb 在第一个参数位置接受数据,您可以使用-> 箭头。如果两个都接受数据在最后一个位置,您可以使用->> 甚至comp,例如。 G。

      (def funcc (comp (partial funcb :add-element {:y 25}) 
                       (partial funca :add-z)))
      

      根据对您正在编写的函数最有用的转换类型,围绕 Clojures 常用的组合工具(箭头和压缩)设计它们的签名。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-05
        • 2014-01-05
        • 1970-01-01
        • 2016-12-21
        • 2013-03-25
        • 2016-02-13
        • 2015-11-06
        相关资源
        最近更新 更多