是否有一个函数的名称,它接受一个数据和一个函数列表,并将每个函数应用于最后一个函数的结果?

Mar*_*mpe 13 ocaml haskell functional-programming function clojure

Clojure的具有宏->,这需要一个数据片和一组函数,所述数据适用于第一功能,然后应用的,为下一个,的结果的结果的是到第三个,等,最后给你回到最后一个申请的结果.

我非常喜欢这个,因为它不必从应用它们的顺序向后编写函数,如下所示:(伪代码跟随)

floor (square.root (x))
Run Code Online (Sandbox Code Playgroud)

您可以按照数据流经它们的顺序编写它们:

-> x (square.root, floor)
Run Code Online (Sandbox Code Playgroud)

我的问题是,在函数式语言中是否有这个函数的标准名称,map,reduce和filter有标准名称吗?Clojure文档将其描述为"通过函数线程化数据",但我在谷歌上找不到任何东西thread.我在Haskell中写了一个简单的版本:

thread :: a -> [(a -> a)] -> a
thread x []     = x
thread x (f:fs) = thread (f x) fs
Run Code Online (Sandbox Code Playgroud)

a -> [(a -> a)] -> a在Hoogle上搜索,但也没有找到任何东西.

在研究这个问题时,我还发现你可以使用Control.ArrowHaskell中的函数组合运算符做一个非常类似的事情,如下所示:

($2) (sin >>> cos >>> tan)
Run Code Online (Sandbox Code Playgroud)

而使用专用的高阶thread函数,你会写:

thread 2 [sin, cos, tan]
Run Code Online (Sandbox Code Playgroud)

是否第一种配方足以满足实际用途?

sku*_*uro 7

您正在寻找的名称是功能组合.

线程宏的区别comp来自于前者利用Clojure的同质性,而后者则更接近于数学定义的组合.

事实上,comp如果每步创建一个参数的函数,则可以将线程宏调用转换为调用,并颠倒函数的顺序:

(defn sin [n] (Math/sin n))
(defn cos [n] (Math/cos n))

(-> 1 sin cos sin cos cos) ; 0.6858966217219662
((comp cos cos sin cos sin) 1) ; 0.6858966217219662
Run Code Online (Sandbox Code Playgroud)


phi*_*mue 4

我认为你可以foldl使用适当的参数来实现这一点:

-- functions for testing
f1 x = x+1
f2 x = x*2
f3 x = x*x
-- here comes the line you're interested in
foldl (\x y -> y x) 2 [f1, f2, f3]
Run Code Online (Sandbox Code Playgroud)

论据如下:

  • (\x y -> y x)是一个函数,接受一个函数y并将其应用于参数xy然后将被列表中的每个函数替换。
  • 2是您想要赋予函数的初始参数。
  • [f1, f2, f3]是函数列表。

使用这些参数,foldl计算以下内容:f3(f2(f1(2)))

  • `(\xy -> yx)` 也可以写成 `(flip ($))` 或(更神秘地)`(flip id)` (7认同)