Add `makeExposed`? #197

Open
ekmett opened this Issue Dec 12, 2012 · 3 comments

Comments

Projects
None yet
2 participants
@ekmett
Owner

ekmett commented Dec 12, 2012

One common objection to lenses is that we can't do type changing assignment to multiple fields simultaneously.

We can. We just need to go into a more permissive type temporarily.

Lets define

class Exposed s t a b | s -> a, t -> b, a -> s, b -> t, s b -> t a, t a -> s b where
  exposed :: Iso s t a b

In general you can then perform polymorphic update with

flip (over exposed) foo $ \x -> x & bar .~ 2 & quux %~ length

as a class like Wrapped or Each, which is more symmetric about type inference.

Ideally if we had

data Quux a b = Quux { _foo :: a, _bar :: b, _baz :: Quux a b } deriving (Eq,Ord,Show,Read)
makeExposed ''Quux

It could generate something like the following test fragment:

{-# LANGUAGE TemplateHaskell, MultiParamTypeClasses, FunctionalDependencies, TypeFamilies, UndecidableInstances, FlexibleInstances #-}
module Tilt where

import Control.Lens

data Quux a b = Quux a b (Quux a b) deriving (Eq,Ord,Show,Read)

data TiltedQuux a b c d = TiltedQuux { _foo :: a, _bar :: b, _baz :: Quux c d }
makeClassy ''TiltedQuux

instance (c ~ a, d ~ b, e ~ g, f ~ h) => Tilted (Quux a b) (Quux e f) (TiltedQuux a b c d) (TiltedQuux e f g h) where
  tilted = iso hither yon where
    hither (Quux a b c) = TiltedQuux a b c
    yon (TiltedQuux a b c) = Quux a b c

instance HasTiltedQuux (Quux a b) a b a b where
  tiltedQuux = tilted

class HasTiltedQuux t a b a b => HasQuux t a b | t -> a b where
  quux :: Simple Lens t (Quux a b)

instance HasQuux (Quux a b) a b where
  quux = id

Here I've moved the definitions to TiltedQuux, but that was just so i could borrow makeClassy.

This requires more extensions than makeClassy does by default, so it shouldn't be the default definition.

But given this you can do polymorphic updates that require multiple fields to change by moving the type equality check to reassembly time.

@ekmett

This comment has been minimized.

Show comment
Hide comment
@ekmett

ekmett Dec 12, 2012

Owner

For this to be useful we also need #128. Otherwise the HasExposedFoo and HasFoo instances will not be able to do type changing assignment.

Owner

ekmett commented Dec 12, 2012

For this to be useful we also need #128. Otherwise the HasExposedFoo and HasFoo instances will not be able to do type changing assignment.

@glguy

This comment has been minimized.

Show comment
Hide comment
@glguy

glguy Feb 8, 2013

Collaborator

I've started on some code to explore this http://hpaste.org/81965

Collaborator

glguy commented Feb 8, 2013

I've started on some code to explore this http://hpaste.org/81965

@ekmett

This comment has been minimized.

Show comment
Hide comment
@ekmett

ekmett Feb 8, 2013

Owner

Nice!

Owner

ekmett commented Feb 8, 2013

Nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment