{-# LANGUAGE ScopedTypeVariables, TypeFamilies, FlexibleContexts, UndecidableInstances #-}moduleSystem.Console.CmdLib.ADTswhereimportSystem.Console.CmdLib.AttributeimportSystem.Console.CmdLib.FlagimportSystem.Console.GetOptimportData.DataimportData.Generics.Aliases(extB)importData.Maybe(fromMaybe)-- | The ADT wrapper type allows use of classic ADTs (algebraic data types) for-- flag representation. The flags are then passed to the command as a list of-- values of this type. However, you need to make the type an instance of the-- Attributes first (if you do not wish to attach any attributes, you may keep-- the instance body empty). E.g.:---- > data Flag = Simplify | Wibblify Int-- > instance Attributes where-- > attributes _ = Wibblify %> Help "Add a wibblification pass." %+ ArgHelp "intensity" %%-- > Simplify %> Help "Enable a two-pass simplifier."---- The "Command" instances should then use @(ADT Flag)@ for their second type-- parameter (the flag type).newtype(Attributesadt)=>ADTadt=ADTadtderivingEqinstance(Eq(ADTadt),Attributesadt,Dataadt)=>FlagType(ADTadt)wheretypeFolded(ADTadt)=[adt]flag_attrkey(ADTx)=KeyC$toConstrxflag_empty_=[]flag_type(ADTflag)_=optionType(gmapQdataTypeOfflag)(gmapQtypeOfflag)flag_list=[ADT$fromConstrx|x<-dataTypeConstrs$dataTypeOf(undefined::adt)]flag_defaultsattr=[(setdeff:)|ADTf<-flag_list,length(gmapQtypeOff)==1,enabled(attr$ADTf)]wheresetdef::adt->adtsetdeff=fromConstrB(defvalue$attrs(ADTf)attr)(toConstrf)flag_attrs(ADTflag)=(attrFun$attributesflag)(KeyC$toConstrflag)%+long(nameFromConstr$toConstrflag)%+defaultsflag_set(ADTflag)v=(fromConstrB((error"flag_set"`extB`v)())(toConstrflag):)flag_parse(ADTflag)str=(fromConstrB(readFlag(undefined::adt)str)(toConstrflag):)flag_args(ADTflag)attr=caseflag_type(ADTflag)attrofBooleanOption->OptArgaddoptional""OptionalArgument->OptArgaddoptional""RequiredArgument->ReqArgadd""SimpleOption->NoArg$(flag:)wherereify::Dataa=>String->areifyy=fromConstrB(readFlag(undefined::adt)y)(toConstrflag)addx=(reifyx:)addoptionalx=(reify(fromMaybe""x):)