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)
是否第一种配方足以满足实际用途?
您正在寻找的名称是功能组合.
线程宏的区别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)
我认为你可以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并将其应用于参数x。y然后将被列表中的每个函数替换。2是您想要赋予函数的初始参数。[f1, f2, f3]是函数列表。使用这些参数,foldl计算以下内容:f3(f2(f1(2)))。