{-# OPTIONS_GHC -fth -cpp #-} -- | Derivation for 'Enum', as defined by the Haskell 98 Language -- report, except that we support arbitrary types. toEnum (and -- derived functions, notably succ and pred) use undefined to fill all -- fields of nonzero arity constructors. module Data.Derive.Enum(makeEnum) where import Language.Haskell.TH.All #ifdef GUESS import Data.DeriveGuess example = (,) "Enum" [d| instance Enum (DataName a) where toEnum 0 = CtorZero{} toEnum 1 = CtorOne {} toEnum 2 = CtorTwo {} toEnum 3 = CtorTwo'{} toEnum n = error $ "toEnum " ++ show n ++ ", not defined for " ++ "DataName" fromEnum (CtorZero{}) = 0 fromEnum (CtorOne {}) = 1 fromEnum (CtorTwo {}) = 2 fromEnum (CtorTwo'{}) = 3 |] #endif makeEnum :: Derivation makeEnum = derivation enum' "Enum" enum' dat = [instance_context [] "Enum" dat [FunD (mkName "toEnum") ((map (\( ctorInd,ctor) -> (Clause [(LitP (IntegerL ctorInd))] (NormalB ((flip RecConE []) (mkName (ctorName ctor)))) [])) (id (zip [0..] (dataCtors dat)) ))++[(Clause [(VarP (mkName "n"))] (NormalB (applyWith (VarE (mkName "$")) [(VarE (mkName "error")),(applyWith (VarE (mkName "++")) [(LitE (StringL "toEnum ")),(applyWith (VarE (mkName "++")) [(AppE (VarE (mkName "show")) ( VarE (mkName "n"))),(applyWith (VarE (mkName "++")) [(LitE (StringL ", not defined for ")),(LitE (StringL (dataName dat)))])])])])) [])]++[]), FunD (mkName "fromEnum") ((map (\(ctorInd,ctor) -> (Clause [((flip RecP []) (mkName (ctorName ctor)))] (NormalB (LitE (IntegerL ctorInd))) [])) (id ( zip [0..] (dataCtors dat))))++[])]]