簡體   English   中英

匯總Haskell記錄列表

[英]Summarize a list of Haskell records

假設我有一個記錄列表,我想通過取中位數來對其進行總結。 更具體地說,說我有

data Location = Location { x :: Double, y :: Double }

我有一個測量值列表,我想將其匯總為一個中值Location ,如下所示:

Location (median (map x measurements)) (median (map y measurements))

很好,但是如果我有更多嵌套的東西,例如:

data CampusLocation = CampusLocation { firstBuilding :: Location
                                      ,secondBuilding :: Location }

我有一個CampusLocation的列表,我想要一個Summary CampusLocation ,其中中值遞歸地應用於所有字段。

在Haskell中最干凈的方法是什么? 鏡片? Uniplate?

編輯:獎金:

如果我們沒有包含要匯總的字段的記錄,而是有一個隱式列表怎么辦? 例如:

data ComplexCampus = ComplexCampus { buildings :: [Location] }

我們怎樣才能總結出[ComplexCampus]ComplexCampus ,假設每個的buildings是一樣的長度?

這是summarize :: [ComplexCampus] -> ComplexCampus ,它使用帶有Uniplate的鏡頭(如您所述)來匯總單個ComplexCampus的ComplexCampus列表。

{-# Language TemplateHaskell,DeriveDataTypeable #-}
import Control.Lens
import Data.Data.Lens
import Data.Typeable
import Data.Data
import Data.List(transpose,genericLength)
data Location = Location { _x :: Double, _y :: Double } deriving(Show,Typeable,Data)


data CampusLocation =  CampusLocation { _firstBuilding :: Location, _firsecondBuilding :: Location }deriving(Show,Typeable,Data)
data ComplexCampus = ComplexCampus { _buildings :: [Location] } deriving(Show,Typeable,Data)


makeLenses ''Location
makeLenses ''CampusLocation
makeLenses ''ComplexCampus

l1 = Location 1 10
l2 = Location 2 20
l3 = Location 3 30


c1 = CampusLocation l1 l2
c2 = CampusLocation l2 l3
c3 = CampusLocation l1 l3
campusLocs = [c1,c2,c3]


c1' = ComplexCampus [l1, l2]
c2' = ComplexCampus [l2, l3]
c3' = ComplexCampus [l1, l3]
campusLocs' = [c1',c2',c3']


average l = (sum l) / (genericLength l)

-- returns average location for a list of locations
averageLoc locs = Location {
             _x = average $ locs ^.. biplate . x,
             _y = average $ locs ^.. biplate . y
             }


summarize :: [ComplexCampus] -> ComplexCampus
summarize ccs = ComplexCampus $ ccs ^.. biplate . buildings ^.. folding transpose . to averageLoc

這里使用雙片很可能矯枉過正,但無論在averageLoc我們使用biplate地區的清單上獲得所有x領域和所有y領域。 如果你想總結出ComplexCampus到一個單一的Location ,我們可以使用biplate提取所有x值和所有y從頂層值ComplexBuilding

例如:

campusLocs' ^.. biplate . x campusLocs' ^.. biplate . x給我們所有的x值和campusLocs' ^.. biplate . y campusLocs' ^.. biplate . y給我們所有y值

同樣,要獲取所有位置,我們可以這樣做:

(campusLocs' ^.. biplate) ::[Location]

或者,如果我們希望每個Double: (campusLocs' ^.. biplate) ::[Double]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM