Arie Peterson writes: > There are two things one typically wants to do when working with a > substructure of some larger data structure: (1) extract the > substructure; and (2) change the larger structure by acting on the > substructure. A 'Ref cx t' encodes both of these functions (for a > substructure of type 't' and larger structure (context) of type 'cx'). > > > data Ref cx t > > = Ref > > { > > select :: cx -> t > > , update :: (t -> t) -> cx -> cx > > } > > A Ref is a bit like a typed and composable incarnation of apfelmus's > indices, or a wrapper around Tillmann's change* functions, containing > not only a setter but also the accompanying getter.
That's a neat idiom. I wonder how far one could usefully generalize it. For example, type Ref cx t = forall f. Functor f => (t -> f t) -> cx -> f cx newtype Id a = Id { unId :: a } instance Functor Id where fmap f = Id . f . unId newtype K t a = K { unK :: t } instance Functor (K t) where fmap = K . unK select :: Ref cx t -> cx -> t select ref = unK . ref K update :: Ref cx t -> (t -> t) -> cx -> cx update ref f = unId . ref (Id . f) rfst :: Ref (a,b) a rfst f (x,y) = fmap (\x' -> (x',y)) (f x) In this implementation, composition of Refs is just function composition. select (rfst . rfst) :: ((a,b),c) -> a -- David Menendez <[EMAIL PROTECTED]> | "In this house, we obey the laws <http://www.eyrie.org/~zednenem> | of thermodynamics!" _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe