{-# LANGUAGE DerivingStrategies, DerivingVia, GeneralizedNewtypeDeriving #-} {-# OPTIONS_GHC -fplugin=Driving.Classes -Wno-unused-top-binds #-} import Control.Applicative (WrappedMonad(..), liftA2) {-# ANN module (Driving :: Driving '[ Stock '(Eq, Ord, Show) , NoDriving '(Eq MyEndo, Ord MyEndo, Show MyEndo) ]) #-} data T1 = C11 | C12 data U1 = D11 | D12 data V1 = E11 | E12 newtype MyEndo a = MyEndo (a -> a) {-# ANN module (Driving :: Driving '[ Newtype Show ]) #-} newtype A2 = A2 Int newtype B2 = B2 A2 newtype C2 = C2 B2 newtype D2 = D2 C2 {-# ANN module (Driving :: Driving '[ Show `Via` Int ]) #-} newtype A3 = A3 Int newtype B3 = B3 A3 newtype C3 = C3 B3 newtype D3 = D3 C3 {-# ANN module (Driving :: Driving '[ '(Functor, Applicative) `ViaF` WrappedMonad , Newtype Monad ]) #-} newtype A4 a = A4 [a] deriving (Eq, Show) newtype B4 a = B4 (IO a) newtype C4 a = C4 (Maybe a) deriving (Eq, Show) main :: IO () main = do -- 1 assertEq (show C11) "C11" assertEq (E11 < E12) True -- 2 assertEq (show ((D2 . C2 . B2 . A2) 0)) "0" -- 3 assertEq (show ((D3 . C3 . B3 . A3) 0)) "0" -- 4 assertEq (liftA2 (+) (A4 [2]) (A4 [1,2 :: Int])) (A4 [3,4]) assertEq (liftA2 (+) (C4 Nothing) (C4 (Just (1 :: Int)))) (C4 Nothing) assertEq :: (Show a, Eq a) => a -> a -> IO () assertEq x y | x == y = pure () assertEq x y = error ("Not equal: " ++ show (x, y))