{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE GADTs #-} {-# 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| Num X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Test X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Eq X |] deriveInstance (isoDeriv [| mkX |] [| unX |] idDeriv) [t| Ord X |] data Rec f = Rec { getUnit :: f (), getInt :: f Int, getX :: f X } deriving instance (Show (f ()), Show (f Int), Show (f X)) => Show (Rec f) deriving instance (Eq (f ()), Eq (f Int), Eq (f X)) => Eq (Rec f) -- deriveInstance (recordDeriv [| Rec |] -- [ ([| getUnit |], apDeriv monoidDeriv) -- , ([| getInt |], apDeriv idDeriv) -- , ([| getX |], apDeriv (isoDeriv [| mkX |] [| unX |] idDeriv)) -- ]) [t| forall f. (Applicative f, Foldable f, Ord (f ()), Ord (f Int), Ord (f X)) => Ord (Rec f) |] deriveInstance showDeriv [t| Test ShowsPrec |] deriveInstance monoidDeriv [t| Test () |] deriveInstance (apDeriv idDeriv) [t| forall a. Test a => Test [a] |] -- deriveInstance (biapDeriv 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) |] deriveInstance (apDeriv monoidDeriv) [t| forall a. Monoid a => Test (IO 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 (biapDeriv idDeriv idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> (a, b)) |] deriveInstance (biapDeriv (apDeriv idDeriv) (newtypeDeriv 'Id 'runId idDeriv)) [t| forall a b. (Test a, Test b) => Test (() -> a, Id b) |] deriveInstance (biapDeriv (monoidDerivBy [| (+) |] [| 0 |]) (monoidDerivBy [| (*) |] [| 1 |])) [t| Test (Int, Int) |] 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) |] class Cotest a where co0 :: a -> Int co1 :: Int -> a -> a co2 :: a -> [[a]] instance (Cotest a, Cotest b) => Cotest (Either a b) where co0 a = either co0 co0 a co1 i a = either (Left . co1 i) (Right . co1 i) a co2 a = either (fmap (fmap Left) . co2) (fmap (fmap Right) . co2) a data Cofree c b where Cofree :: c a => (a -> b) -> a -> Cofree c b instance Cotest (Cofree Cotest a) where co0 (Cofree _ a) = co0 a co1 i (Cofree k a) = Cofree k (co1 i a) co2 (Cofree k a) = fmap (fmap (Cofree k)) (co2 a)