Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure:组合arity 2(或更高)的函数_Clojure_Functional Programming_Function Composition_Arity - Fatal编程技术网

Clojure:组合arity 2(或更高)的函数

Clojure:组合arity 2(或更高)的函数,clojure,functional-programming,function-composition,arity,Clojure,Functional Programming,Function Composition,Arity,根据参数,我使用可变数量的函数处理数据。每个处理函数都将从其前一个函数接收数据,对其进行处理并将其传递给下一个函数 (defn example [data] (do-things-to data)) 我的申请流程是 检查参数并将所需函数存储在向量中 创建一个包含所有必要步骤的函数 调用进行文件管理并最终应用该函数的包装器函数 模型: (let [my-big-fun (reduce comp (filter identity) vector-of-functions)] (wrappe

根据参数,我使用可变数量的函数处理数据。每个处理函数都将从其前一个函数接收数据,对其进行处理并将其传递给下一个函数

(defn example [data]
  (do-things-to data))
我的申请流程是

  • 检查参数并将所需函数存储在向量中
  • 创建一个包含所有必要步骤的函数
  • 调用进行文件管理并最终应用该函数的包装器函数
  • 模型:

    (let [my-big-fun (reduce comp (filter identity) vector-of-functions)]
      (wrapper lots-a-arguments big-fun)
    
    现在我发现我不仅需要将数据传递给函数,还需要另一个数据集

    (defn new-fun-example [root data]
      (do-things-to-both root data))
    
    有没有类似于我对arity-1函数所做的简化的方法?简单的
    juxt
    不行,因为每个函数都会更改下一个函数所需的数据。返回
    '(根数据)
    序列或类似序列需要在许多函数中进行大量重写

    有什么想法吗?我猜答案是“宏”,但我从来没有摆弄过这些

    编辑1:

    第二个参数是对不断增长的图形数据结构的引用,因此它不需要由函数处理,只需以某种方式传递。 但是这些函数可能来自不同的名称空间,所以我不能简单地将根放在更高的范围内来访问它。一个全局的
    def
    是可能的,但是非常难看

    在写这篇文章时,我只是想在编译函数之前,以某种方式将函数映射到
    partial

    编辑2:

    过滤器标识
    造成了很多混乱,这不是我的问题。我本来不应该把它包括在我的样品里。我按照敏捷的棕色狐狸的建议解决了任务,并为自己有时的默默无闻而道歉。最小解决方案,如示例:

    (defn example [root data]
      (swap! root + data))
    
    (defn fn-chainer [vector-of-functions]
      (let [the-root (atom 0)
        ; this filter step is just required to remove erroneously apperaring nils 
        ; from the vector of functions - not part of the question
        vector-of-functions (filter identity vector-of-functions)
        ; bake the atom to the functions
        vector-of-functions (mapv #(partial % the-root) vector-of-functions)
        ; now chain each funcion's result as argument to the next one
        my-big-fun (reduce comp vector-of-functions)]
        ; let the function chain process some dataset
        (my-big-fun 5))
    
    ; test some function vectors
    (fn-chainer [example])
    => 5    ; = 0 + 5
    (fn-chainer [example example])
    => 10   ; = 0 + 5 +5
    (fn-chainer [example nil example example nil nil])10
    => 20   ; = 0 + 5 + 5 + 5 + 5, nils removed
    

    首先,我觉得这里发生了很多事情:

  • (过滤器标识)
    是一个传感器,但没有说明其他FN返回传感器,或者如果wrapper需要一个传感器,并且鉴于其中一些传感器将接收两个参数,我们可以放心地说它们不是传感器。您可能想要
    (部分筛选标识)
    #(筛选标识%)

  • 为什么要使用
    (减少函数的comp(过滤器标识)向量)
    而不是
    (应用函数的comp(cons(部分过滤器标识)向量)

  • 如果函数中的某些函数接收到更多参数,而您已经有了这些参数的值,那么您可以使用partial:

    (let [root [1 2 3]
          other-root [4 5 6]
          vector-of-functions [(partial filter identity) example (partial my-fun-example root) (partial other-fun-example root other-root)]
          my-big-fun (apply comp vector-of-functions)]
      (wrapper lots-a-arguments big-fun))
    

    编辑:对于上面的应用comp,我错误地使用了
    reverse
    (reduce comp[fn1 fn2 fn3])
    将返回与
    (apply comp[fn1 fn2 fn3])
    相同的结果。当应用时,正如您在编辑中提到的,您确实可以将函数映射到具有
    根的新函数中:

    (mapv #(partial % root) vector-of-functions)
    

    我不知道如何用arity 2组合两个函数,因为每个函数只能产生一个输出。每个函数的输出是由两个项组成的序列吗?不,不是。另一方面,第二个输入(
    root
    ,在示例中)是常量,它是对数据结构根的引用。好问题。1.我只是过滤函数向量,这样我就不会在开发阶段2意外地将
    nil
    s压缩。因为我是clojure的新手,从未完全掌握
    apply
    :-)的概念,它会更适合吗?如果是,为什么?我只是在你输入答案时编辑了关于使用
    部分
    的想法,所以我很高兴你也这么建议。您的解决方案中唯一的“但是”是:向量是以编程方式填充的,因此我需要调用
    map
    ?要添加
    部分根
    我不确定。Re“只需过滤函数向量”:那么函数向量中的元素可能为零,或者输入(或输出)数据序列中的元素可能在comp之后?如果是前者,我会在你到达这一点之前做过滤。函数的一个先决条件是函数的
    向量
    没有任何零。重新应用:请参阅。您可以使用
    (reduce comp…
    ,但在我看来,它不太惯用。但您会看到一些人的说法正好相反。YMMV。无论如何,我认为首先更清楚地了解
    (过滤器标识)
    是很重要的。如果我们能把它从问题中去掉,那就更好了:)Re“向量是以编程方式填充的”:不管它是“以编程方式”(通过一个接一个地连接函数,通过concat较小的函数向量等)还是“手工”(通过向量文本)填充的,在这两种情况下,您都会在
    函数向量中引用向量
    ,因此除了
    (应用comp函数向量)
    (或
    reduce
    )之外,您似乎不需要地图或其他任何东西。啊,现在我了解您的担忧。无论如何,谢谢你的解释。