derive-2.6: src/Data/Derive/Has.hs
{-|
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"]