{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TemplateHaskell #-} module Test where import Data.DeriveLiftedInstances import Data.Functor.Identity class Test a where op0 :: a op1 :: Int -> [a] -> a op2 :: [[a]] -> a instance Test Int where op0 = 1 op1 i is = i + sum is op2 = sum . fmap sum newtype X = X { unX :: Int } deriving Show mkX :: Int -> X mkX = X . (`mod` 10) deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Test X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Eq X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Ord X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Num X |] deriveInstance showDeriv [t| Test ShowsPrec |] deriveInstance unitDeriv [t| Test () |] deriveInstance (apDeriv idDeriv) [t| forall a. Test a => Test [a] |] deriveInstance (tupleDeriv idDeriv idDeriv) [t| forall a b. (Test a, Test b) => Test (a, b) |] -- deriveInstance (newtypeDeriv 'Identity 'runIdentity idDeriv) [t| forall a. Test a => Test (Identity a) |] newtype Ap f a = Ap { getAp :: f a } deriving Show deriveInstance (newtypeDeriv 'Ap 'getAp (apDeriv idDeriv)) [t| forall f a. (Applicative f, Test a) => Test (Ap f a) |] deriveInstance (newtypeDeriv 'Identity 'runIdentity (newtypeDeriv 'Ap 'getAp (apDeriv idDeriv))) [t| forall f a. (Applicative f, Test a) => Test (Identity (Ap f a)) |] newtype Id a = Id { runId :: a } deriveInstance (apDeriv (apDeriv (newtypeDeriv 'Id 'runId idDeriv))) [t| forall a. Test a => Test (() -> Identity (Id a)) |] deriveInstance (apDeriv (tupleDeriv idDeriv idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> (a, b)) |] deriveInstance (tupleDeriv (apDeriv idDeriv) (newtypeDeriv 'Id 'runId idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> a, Id b) |] class Test1 f where hop0 :: f a hop0' :: f Int hop1 :: Int -> f Int -> f Int instance Test1 [] where hop0 = [] hop0' = [1] hop1 i = map (+ i) deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Test1 f => Test1 (Ap f) |] deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Functor f => Functor (Ap f) |] deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Applicative f => Applicative (Ap f) |] deriveInstance (newtypeDeriv 'Ap 'getAp idDeriv) [t| forall f. Monad f => Monad (Ap f) |]