on master help sign in
Optimise 'field' lens with Coyoneda
commit5da262dc4a970c2579f4536648b8fe1c53021d4a authorCsongor Kiss <kiss.csongor.kiss@gmail.com> dateWed 6 Sep 2017, 10:25 (9 years ago) parentea95d4d
2 files changed+20−2
src/Data/Generics/Internal/Lens.hs+19−1 src/Data/Generics/Product/Fields.hs+1−1
src/Data/Generics/Internal/Lens.hs+19−1
@@ -1,4 +1,5 @@
1−{-# LANGUAGE Rank2Types #-}
1+{-# LANGUAGE GADTs #-}
2+{-# LANGUAGE Rank2Types #-}
23{-# LANGUAGE TypeOperators #-}
34
45-----------------------------------------------------------------------------
@@ -89,3 +90,20 @@ _Left = prism Left $ either Right (Left . Right)
8990
9091_Right :: Prism' (Either c a) a
9192_Right = prism Right $ either (Left . Left) Right
93+
94+--------------------------------------------------------------------------------
95+
96+data Coyoneda f b = forall a. Coyoneda (a -> b) (f a)
97+
98+instance Functor (Coyoneda f) where
99+ fmap f (Coyoneda g fa)
100+ = Coyoneda (f . g) fa
101+
102+inj :: Functor f => Coyoneda f a -> f a
103+inj (Coyoneda f a) = fmap f a
104+
105+proj :: Functor f => f a -> Coyoneda f a
106+proj fa = Coyoneda id fa
107+
108+ravel :: Functor f => ((a -> Coyoneda f b) -> s -> Coyoneda f t) -> (a -> f b) -> (s -> f t)
109+ravel coy f s = inj $ coy (\a -> proj (f a)) s
src/Data/Generics/Product/Fields.hs+1−1
@@ -91,7 +91,7 @@ instance
9191 , GHasField field (Rep s) a
9292 ) => HasField field a s where
9393
94− field = repIso . gfield @field
94+ field = ravel (repIso . gfield @field)
9595
9696type family ErrorUnless (field :: Symbol) (s :: Type) (contains :: Bool) :: Constraint where
9797 ErrorUnless field s 'False