是否可以编写一个采用map,reduce或filter的函数并返回它们的"函数化"版本?

Mar*_*mpe 3 haskell functional-programming

请原谅我缺乏适当的术语 - 我对--morphisms等一无所知,但我觉得我试图表达的概念可以通过某种术语来描述.

映射,缩小和过滤,经典的高阶函数,都具有获取函数f和数据列表xs以及f对所有数据执行某些操作的一般结构xs.现在,他们每个人,我能想象一个"functionised"版本- mapf给他们打电话,reducef和filterf -这不是需要一个数据块x和功能的列表fs并执行每个功能fs的数据x.具体来说,mapf会返回一个列表f1(x), f2(x), ...,reducef会给你f3 (f2 (f1 (x)))或者f1 (f2 (f3 (x)))(取决于它是左还是右),filterf会测试每个是否f1(x), f2(x), ...为真,只返回fs那些.

我的问题是:是否可以编写一个通用函数,functionise它将map,reduce或filter作为参数并生成相应的mapf,reducef或filterf函数?(当然,优雅的方式不仅仅是一系列的案例表达.)

我不介意使用什么编程语言; 在我自己的实验中,我一直在使用Haskell,而导致我这个问题的原因是我注意到所有三个函数都可以用非常类似的方式定义:

rev = \x y -> y x

mapf :: a -> [a -> b] -> [b]
mapf x fs = map (rev x) fs

reducef :: a -> [a -> a] -> a
reducef x fs = foldl rev x fs

filterf :: a -> [a -> Bool] -> [a -> Bool]
filterf x fs = filter (rev x) fs
Run Code Online (Sandbox Code Playgroud)

我对它们的相似性很感兴趣,所以我想要发现它是可能的,并且看看如何,或者被证明它是不可能的,并且看到原因.正如我所说,编程语言并不重要,所以我不介意它是否可能在语言A中而不是在语言B中,因为语言B的类型系统 - 这很有趣.

谢谢!

Ing*_*ngo 16

没有意义淡化你的想法,但这是不值得的努力.例如,将函数列表应用于值将是:

map ($ v) [f1, f2, f3]
Run Code Online (Sandbox Code Playgroud)

mapf只是另一个专业map

mapf :: v -> [(v -> a)] -> [a]
mapf v fs = map ($v) fs
Run Code Online (Sandbox Code Playgroud)

  • 同样`filterf v fs = filter($ v)fs` (2认同)

ham*_*mar 5

reducef与其他模式不完全相同,但对于mapfilter,模式是\g x fs -> g (rev x) fs,或(. rev)简称:

> :t (. rev) map
(. rev) map :: a -> [a -> t] -> [t]
> :t (. rev) filter
(. rev) filter :: a -> [a -> Bool] -> [a -> Bool]
Run Code Online (Sandbox Code Playgroud)

如果你想包括reducef,你需要一个稍微不同的模式,\g x fs -> g rev x fs可以缩短为($ rev):

> :t ($ rev) foldl
($ rev) foldl :: t -> [t -> t] -> t
Run Code Online (Sandbox Code Playgroud)

它不会工作就mapfilter直接,但你可以使用它(map .)(filter .):

> :t ($ rev) (map .)
($ rev) (map .) :: t1 -> [t1 -> t] -> [t]
> :t ($ rev) (filter .)
($ rev) (filter .) :: t1 -> [t1 -> Bool] -> [t1 -> Bool]
Run Code Online (Sandbox Code Playgroud)

所以我认为functionalise = ($ rev)尽可能接近你.