{-| Has is a pseudo derivation. For each field of any constructor of the data type, Has generates @has@/FieldName/ which returns 'True' if given the the given field is a member of the constructor of the passed object, and 'False' otherwise. -} module Data.Derive.Has(makeHas) where {- test :: Computer hasSpeed :: Computer -> Bool hasSpeed _ = True hasWeight :: Computer -> Bool hasWeight Laptop{} = True hasWeight _ = False test :: Sample -} import Language.Haskell import Data.Derive.Internal.Derivation import Data.List makeHas :: Derivation makeHas = derivationCustom "Has" $ \(_,d) -> Right $ concatMap (makeHasField d) $ dataDeclFields d makeHasField :: DataDecl -> String -> [Decl ()] makeHasField d field = if isIdent field then [TypeSig () [name has] typ, binds has ms] else [] where has = "has" ++ title field typ = TyFun () (dataDeclType d) (tyCon "Bool") (yes,no) = partition (elem field . map fst . ctorDeclFields) $ dataDeclCtors d match pat val = ([pat], con val) ms | null no = [match (PWildCard ()) "True"] | otherwise = [match (PRec () (qname $ ctorDeclName c) []) "True" | c <- yes] ++ [match (PWildCard ()) "False"]