derive-0.1: 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
import Language.Haskell.TH.All
import Data.Char
import Data.List
{-
data Computer = Laptop {weight :: Int, memory :: Int}
| Desktop {memory :: Int, processor :: Int}
==>
hasWeight (Laptop{}) = True
hasWeight _ = False
hasMemory (Laptop{}) = True
hasMemory (Desktop{}) = True
hasProcessor (Desktop{}) = True
hasProcessor _ = False
-}
makeHas :: Derivation
makeHas = Derivation has' "Has"
has' dat = map f fields
where
ctors = dataCtors dat
fields = nub $ concatMap ctorFields ctors
f field = funN ("has" ++ toUpper (head field) : tail field) $
[sclause [RecP (mkName $ ctorName c) []] true | (True,c) <- zip matches ctors] ++
[sclause [WildP] false | not $ and matches]
where
matches = map (\c -> field `elem` ctorFields c) ctors