2012-03-04 25 views
3

請原諒我缺乏正確的術語 - 我對「形態」等知之甚少,但我有這樣的感覺,即我想表達的概念可以用某種術語來描述。是否有可能編寫一個函數,該函數使用map,reduce或filter並返回它們的「功能化」版本?

地圖,減少和過濾器,經典的高階功能,都具有利用函數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函數? (當然,優雅的方式,不只是作爲一系列案例表達式。)

我不介意使用什麼編程語言;在我自己的實驗,我一直在使用哈斯克爾,和這導致了我對這個問題的是,我注意到,所有三個功能可以在一個非常類似的方式來定義:

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 

我被tantalised他們的相似性,所以我想要知道這是可能的,並且看看如何或者被證明這是不可能的,並且看看爲什麼。正如我所說的,編程語言並不重要,所以我不介意在語言A中是否可能,但由於語言B的類型系統而不是在語言B中 - 這很有趣。

謝謝!

回答

3

你的代碼只是一個專業化類似於我發現了隱藏在「搖擺」 wiki under pointfree

swing f c a = f ($ a) c 

swing map :: forall a b. [a -> b] -> a -> [b] 
swing any :: forall a. [a -> Bool] -> a -> Bool 
swing foldr :: forall a b. b -> a -> [a -> b -> b] -> b 
swing zipWith :: forall a b c. [a -> b -> c] -> a -> [b] -> [c] 
swing find :: forall a. [a -> Bool] -> a -> Maybe (a -> Bool) 

-- applies each of the predicates to the given value, returning the first 
-- predicate which succeeds, if any 

swing partition :: forall a. [a -> Bool] -> a -> ([a -> Bool], [a -> Bool]) 
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] 

如果你想包括reducef,你」會需要一個稍微不同的模式,\g x fs -> g rev x fs,可縮短爲($ rev)

> :t ($ rev) foldl 
($ rev) foldl :: t -> [t -> t] -> t 

它不會對工作和filter直接,但你可以用它(map .)(filter .)

> :t ($ rev) (map .) 
($ rev) (map .) :: t1 -> [t1 -> t] -> [t] 
> :t ($ rev) (filter .) 
($ rev) (filter .) :: t1 -> [t1 -> Bool] -> [t1 -> Bool] 

所以我認爲functionalise = ($ rev)大約是接近你可以得到的。

16

沒有意思淡化你的想法,但它是不值得的努力。例如,以功能列表應用於值是:

map ($ v) [f1, f2, f3] 

mapfmap

mapf :: v -> [(v -> a)] -> [a] 
mapf v fs = map ($v) fs 
+2

同樣'filterf v fs = filter($ v)fs' – rampion 2012-03-04 14:27:58

相關問題