gpt4 book ai didi

haskell - 汇总 Haskell 记录列表

转载 作者:行者123 更新时间:2023-12-03 15:06:07 28 4
gpt4 key购买 nike

假设我有一个记录列表,我想通过取中位数来总结它。更具体地说,说我有

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 的列表s 和我想要一个摘要 CampusLocation ,其中中位数递归地应用于所有字段。

在 Haskell 中最干净的方法是什么?镜头?单板?

编辑:奖金:

如果我们想要汇总的不是包含字段的记录,而是一个隐式列表,该怎么办?例如:
data ComplexCampus = ComplexCampus { buildings :: [Location] }

我们如何总结 [ComplexCampus]变成 ComplexCampus ,假设每个 buildings长度一样吗?

最佳答案

这是 summarize :: [ComplexCampus] -> ComplexCampus 的实现它使用带有 Uniplate 的 Lenses(如您所提到的)来汇总 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给我们所有的 x 值和 campusLocs' ^.. biplate . y给我们所有的 y 值

同样,要获取所有位置,我们可以这样做:
(campusLocs' ^.. biplate) ::[Location]
或者,如果我们想要每个 Double: (campusLocs' ^.. biplate) ::[Double]

关于haskell - 汇总 Haskell 记录列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25540407/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com