Closed Lysxia closed 2 years ago
I implemented something similar because I needed it myself. This is what I came up with:
data OnField (s :: Symbol) (f :: Type -> Type) :: Type
type instance GSurgery (OnField x f) g = GOnField x f g
type family GOnField (x :: Symbol) (f :: Type -> Type) (g :: k -> Type) :: k -> Type where
GOnField x f (M1 S ('MetaSel ('Just x) a b c) r) = M1 S ('MetaSel ('Just x) a b c) (GOnField x f r)
GOnField x f (M1 C m r) = M1 C m (GOnField x f r)
GOnField x f (M1 D m r) = M1 D m (GOnField x f r)
GOnField x f (M1 s m r) = M1 s m r
GOnField x f (r :+: s) = GOnField x f r :+: GOnField x f s
GOnField x f (r :*: s) = GOnField x f r :*: GOnField x f s
GOnField x f (K1 i a) = K1 i (f a)
GOnField x f U1 = U1
GOnField x f V1 = V1
It's used just like OnFields
, but you write OnField "foo" Sum
or similar. It's not quite as general as your OverrideFields
, but it is quite simple. I can PR if you like, or you can just copy the code from here if you like it.
Thanks, that looks good! I can do it when I get around to it soon. The one change I will add is to defunctionalize the (EDIT: changed my mind, cf. #50 )K1 i (f a)
case so the resulting field can be something other than a type application.
Do this: https://gist.github.com/sjoerdvisscher/480ea5755477b5da580ca3708991fb05