implementation of transform using generics
data Expr | |
= Lit Int | |
| Add Expr Expr | |
| Mul Expr Expr | |
| Div Expr Expr | |
| Sub Expr Expr | |
| Neg Expr | |
deriving (Show, Eq, Generic) | |
-- Transform -- | |
class GTransform a struct where | |
gtransform :: (a -> a) -> struct x -> struct x | |
instance GTransform a U1 where | |
gtransform _ U1 = U1 | |
instance GTransform a V1 where | |
gtransform _ x = x | |
instance {-# OVERLAPPING #-} Transform a => GTransform a (K1 _1 a) where | |
gtransform f (K1 a) = K1 (f $ transform f a) | |
instance Transform b => GTransform a (K1 _1 b) where | |
gtransform f (K1 b) = K1 (transform f b) | |
instance (GTransform a x, GTransform a y) => GTransform a (x :+: y) where | |
gtransform f = \case | |
L1 x -> L1 $ gtransform f x | |
R1 y -> R1 $ gtransform f y | |
instance (GTransform a x, GTransform a y) => GTransform a (x :*: y) where | |
gtransform f (x :*: y) = gtransform f x :*: gtransform f y | |
instance GTransform a struct => GTransform a (M1 _x _y struct) where | |
gtransform f (M1 a) = M1 $ gtransform f a | |
class Transform x where | |
transform :: (a -> a) -> x -> x | |
default transform :: forall a. (Generic x, GTransform a (Rep x)) => (a -> a) -> x -> x | |
transform f = to . gtransform f . from | |
instance Transform Int where | |
transform = flip const | |
instance Transform Expr | |
{- ^ | |
generics.hs:101:10: error: | |
• Overlapping instances for GTransform a (K1 R Int) | |
arising from a use of ‘Main.$dmtransform’ | |
Matching instances: | |
two instances involving out-of-scope types | |
(use -fprint-potential-instances to see them all) | |
(The choice depends on the instantiation of ‘a’ | |
To pick the first instance above, use IncoherentInstances | |
when compiling the other instance declarations) | |
• In the expression: Main.$dmtransform @(Expr) | |
In an equation for ‘transform’: | |
transform = Main.$dmtransform @(Expr) | |
In the instance declaration for ‘Transform Expr’ | |
| | |
101 | instance Transform Expr | |
| ^^^^^^^^^^^^^^ | |
-} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment