这里是一个使用Lenses w/ Uniplate实现的
summarize :: [ComplexCampus] -> ComplexCampus
函数,用于将一系列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)
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
从顶级ComplexBuilding
中提取所有x
值和y
值。
例如:
campusLocs' ^.. biplate . x
给我们所有的x值,而 campusLocs' ^.. biplate . y
则给我们所有的y值。
同样,要获取所有位置,我们只需要执行:
(campusLocs' ^.. biplate) ::[Location]
或者,如果我们想要每个Double:
(campusLocs' ^.. biplate) ::[Double]
forall f. Traversable f => (f a -> b) -> (f s -> t)
的“应用器”。不知道是否有人已经考虑过这些。 - Ørjan JohansenFunctor
之外,他说这已经足够了)将是一个“cotraversal”。为了使问题中的类型实际上是“可分配的”,它们需要将Double
更改为类型参数。 - Ørjan JohansenProfunctor p => p a b -> p s t
上运行得相当好,其中我们通过要求p是“可表示”的Profuctor来恢复Van Laarhoven公式。因此,在您的镜头中,您需要一个“核心表现”Profuctor。 - J. Abrahamson