2015-10-19 32 views
-2

我有一個記錄/元組列表。和一些在列表上處理的函數。就像max_min那樣需要一個列表並返回min,max對。 有什麼方法可以不加修改地組合這些功能? 每個功能都不會對原始列表進行任何修改。 但可能會減少,地圖,過濾器。列表上的多個函數

stream ---> Process1 ----> Process2 

    [ (x:4,y:2,value:10) , (x:3,y:1,value:2), ... ] 

    function min_max (list) = .... a function that takes a list and return (min,max) pair 

    function count(list) = .... count occurrences and return [(item, times)] 
    function average(list) = .... 

在命令式的方式,我可以只使用一個大的for循環,包括內部的每個函數的所有邏輯。 有沒有優雅的方式來做到這一點?

在Python中,生成器發送可以發送每個列表元素到所有函數。我認爲這可能有效。 如何以功能的方式抽象出這個?單子?折?

+3

這個問題關於什麼編程語言? Perl,Python或Haskell?請刪除不適用的語言標記。 – simbabque

+0

min/max/count - 如果摺疊函數由使用的函數組成,則平均值不會進入一次 - 因爲sum和len的除法操作不適合摺疊 - 但它可以很容易之後完成 – epsilonhalbe

+0

但我建議從一個簡單的開始 - 在每個步驟之後執行另一個程序 - 請參閱測量它是否足夠快(如果您使用的是haskell,我會推薦'標準'),並且僅當它不是 - 然後開始寫一個組合的摺疊函數 - 並記錄它做了什麼以及爲什麼選擇這麼做(例如,出於性能原因) – epsilonhalbe

回答

3

在Haskell中,簡單的方法是使用Gabriel Gonzalez的foldl包。此包支持Fold類型,表示您在摺疊到容器上時要執行的所有計算,以及如何組合/變換這些計算的結果。你可以寫如

import Control.Foldl as L 

avg :: (Foldable f, Fractional n) => f n -> n 
avg = L.fold $ (/) <$> L.sum <*> (fromIntegral <$> L.length) 

產生一個函數,計算容器的元素的平均值。該包裝是「含電池」,提供相當多的基本操作作爲構建模塊使用,但如果需要,您也可以編寫自己的Fold。如果您的應用程序需要,編寫函數以將Fold應用於流式源代碼而非可摺疊容器也非常容易。