Diciamo che ho un elenco di record e voglio riassumerlo prendendo la mediana. Più concretamente, dire che hoRiassumi un elenco di record Haskell
data Location = Location { x :: Double, y :: Double }
Ho un elenco di misure, e voglio riassumere in una mediana Location
, quindi qualcosa di simile:
Location (median (map x measurements)) (median (map y measurements))
Questo va bene, ma che cosa succede se io avere qualcosa in più nidificato, come ad esempio:
data CampusLocation = CampusLocation { firstBuilding :: Location
,secondBuilding :: Location }
ho una lista di CampusLocation
s e voglio una sintesi CampusLocation
, in cui la mediana è applicato in modo ricorsivo a tutti campi.
Qual è il modo più pulito per farlo in Haskell? Lenti? UniPlate?
Edit: Bonus:
Che cosa succede se invece di un record che contiene i campi che vogliamo riassumere, avevamo una lista implicita, invece? Per esempio:
data ComplexCampus = ComplexCampus { buildings :: [Location] }
Come possiamo riassumere un [ComplexCampus]
in un ComplexCampus
, supponendo che ciascuna delle buildings
è la stessa lunghezza?
I a Improvvisamente immaginando questo tipo di cose si adatterebbe un "doppio" traversamento di obiettivi: "applicativi" con tipo 'forall f. Traversable f => (f a -> b) -> (f s -> t) '. Non ho idea se qualcuno ha ancora pensato a quelli. –
@ ØrjanJohansen Non sono sicuro se questo è rilevante qui, ma c'è un "cotraverse" in [distributive] (http://hackage.haskell.org/package/distributive-0.4.4/docs/Data-Distributive. html). –
@ AndrásKovács Questo sembra rilevante e avrei dovuto ricordarlo. Secondo il solito schema di denominazione di Kmett, quello che ho suggerito (eccetto che con 'Functor', che dice è sufficiente) sarebbe un" cotraversal "allora. Per rendere effettivamente i tipi nella domanda 'distributive', dovrebbero cambiare' Double' in un parametro type. –