多个名称空间;试图在一个方法中调用方法,将输出传递给第三个方法中的另一个方法

时间:2016-10-19 14:13:36

标签: methods clojure namespaces

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

(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))

我有第3个名称空间定义为

(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}。< / p>

在尝试定义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时,我正在

  

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

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

2 个答案:

答案 0 :(得分:0)

  

这应该取(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的{​​{1}}结果应用于funca并使用某些数据,则可以将其更改为:

add-z

并称之为:

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

答案 1 :(得分:0)

使用as-&gt;宏

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

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

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

根据您正在编写的函数最有用的转换类型,在Clojures常用合成工具(箭头和补偿)周围设计签名。