domain-0.1.1.5: library/Domain/TH/InstanceDecs.hs
module Domain.TH.InstanceDecs where
import Domain.Prelude
import qualified Domain.TH.InstanceDec as InstanceDec
import DomainCore.Model
import qualified Language.Haskell.TH as TH (Dec)
hasField :: TypeDec -> [TH.Dec]
hasField (TypeDec typeName typeDef) =
case typeDef of
ProductTypeDef members ->
zipWith zipper (enumFrom 0) members
where
numMembers =
length members
zipper offset (fieldName, fieldType) =
InstanceDec.productHasField typeName fieldName fieldType numMembers offset
SumTypeDef variants ->
fmap mapper variants
where
mapper (variantName, memberTypes) =
InstanceDec.sumHasField typeName variantName memberTypes
accessorIsLabel :: TypeDec -> [TH.Dec]
accessorIsLabel (TypeDec typeName typeDef) =
case typeDef of
ProductTypeDef members ->
zipWith zipper (enumFrom 0) members
where
numMembers =
length members
zipper offset (fieldName, fieldType) =
InstanceDec.productAccessorIsLabel typeName fieldName fieldType numMembers offset
SumTypeDef variants ->
variants
& fmap
( \(variantName, memberTypes) ->
InstanceDec.sumAccessorIsLabel typeName variantName memberTypes
)
constructorIsLabel :: TypeDec -> [TH.Dec]
constructorIsLabel (TypeDec typeName typeDef) =
case typeDef of
ProductTypeDef members ->
[]
SumTypeDef variants ->
variants
& fmap
( \(variantName, memberTypes) ->
InstanceDec.curriedSumConstructorIsLabel typeName variantName memberTypes
)
variantConstructorIsLabel :: Text -> (Text, [Type]) -> [TH.Dec]
variantConstructorIsLabel typeName (variantName, memberTypes) =
let curried =
InstanceDec.curriedSumConstructorIsLabel typeName variantName memberTypes
uncurried =
InstanceDec.uncurriedSumConstructorIsLabel typeName variantName memberTypes
in case memberTypes of
[] ->
[curried]
[_] ->
[curried]
_ ->
[curried, uncurried]
mapperIsLabel :: TypeDec -> [TH.Dec]
mapperIsLabel (TypeDec typeName typeDef) =
case typeDef of
ProductTypeDef members ->
zipWith zipper (enumFrom 0) members
where
numMembers =
length members
zipper offset (fieldName, fieldType) =
InstanceDec.productMapperIsLabel typeName fieldName fieldType numMembers offset
SumTypeDef variants ->
do
(variantName, memberTypes) <- variants
if null memberTypes
then empty
else pure (InstanceDec.sumMapperIsLabel typeName variantName memberTypes)
-- * Deriving
-------------------------
byNonAliasName :: (Text -> TH.Dec) -> TypeDec -> [TH.Dec]
byNonAliasName cont (TypeDec a b) =
[cont a]
byEnumName :: (Text -> TH.Dec) -> TypeDec -> [TH.Dec]
byEnumName cont (TypeDec name def) =
case def of
SumTypeDef variants
| all (null . snd) variants ->
[cont name]
_ ->
[]
enum :: TypeDec -> [TH.Dec]
enum =
byEnumName (InstanceDec.deriving_ ''Enum)
bounded :: TypeDec -> [TH.Dec]
bounded =
byEnumName (InstanceDec.deriving_ ''Bounded)
show :: TypeDec -> [TH.Dec]
show =
byNonAliasName (InstanceDec.deriving_ ''Show)
eq :: TypeDec -> [TH.Dec]
eq =
byNonAliasName (InstanceDec.deriving_ ''Eq)
ord :: TypeDec -> [TH.Dec]
ord =
byNonAliasName (InstanceDec.deriving_ ''Ord)
generic :: TypeDec -> [TH.Dec]
generic =
byNonAliasName (InstanceDec.deriving_ ''Generic)
data_ :: TypeDec -> [TH.Dec]
data_ =
byNonAliasName (InstanceDec.deriving_ ''Data)
typeable :: TypeDec -> [TH.Dec]
typeable =
byNonAliasName (InstanceDec.deriving_ ''Typeable)
hashable :: TypeDec -> [TH.Dec]
hashable =
byNonAliasName (InstanceDec.empty ''Hashable)
lift :: TypeDec -> [TH.Dec]
lift =
byNonAliasName (InstanceDec.deriving_ ''Lift)