{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} module T10361b where import GHC.Generics --------------------------------------------------------------------- class Convert a where type Result a type instance Result a = GResult (Rep a) convert :: a -> Result a default convert :: (Generic a, GConvert (Rep a)) => a -> GResult (Rep a) convert x = gconvert (from x) instance Convert Float where type Result Float = Float convert = id instance Convert Int where type Result Int = Int convert = id --------------------------------------------------------------------- class GConvert f where type GResult f gconvert :: f p -> GResult f instance (Convert c) => GConvert (K1 i c) where type GResult (K1 i c) = Result c gconvert (K1 x) = convert x instance (GConvert f) => GConvert (M1 i t f) where type GResult (M1 i t f) = GResult f gconvert (M1 x) = gconvert x instance (GConvert f, GConvert g) => GConvert (f :*: g) where type GResult (f :*: g) = (GResult f, GResult g) gconvert (x :*: y) = (gconvert x, gconvert y) --------------------------------------------------------------------- data Data1 = Data1 Int Float deriving (Generic) instance Convert Data1 val :: (Int, Float) val = convert $ Data1 0 0.0 data Data2 = Data2 Int Float deriving (Generic, Convert)