简体   繁体   中英

Constraining types in GADT constructor

I've a simple ADT

data Concept a = Entity  a |  Role a | Relation a | Resource a | Sub (Concept a)

Now I want to create a GADT using this ADT that will constrain the type signature of it's constructors. This code won't work but I want to do something like this:

data Construct a b where
      Has :: Concept a -> 'Resource b -> Construct (Concept a) ('Resource b)

Ie Has constructor for Construct can have first type param as a Concept of any form but the second type param should be a Resource constructor (promoted to be a type). This signature is failing as am using kind in place of type. But I want to realise something like this and am failing to wrap my head around how to do the same.

I'm importing {-# LANGUAGE GADTs, TypeInType #-} .

Edit:

Based on one comment, if I do this

 data Construct (a :: Concept ak) (b :: Concept bk)  where
  Has :: Construct a ('Resource b)

Then it's is type-checking. But now how can I extract values when pattern matching on Has

f :: Construct a b -> T.Text
f Has = ???

My requirement is I want to constrain types for Has ab constructor so that it can only allow a :: Concept ak (ie any Concept) and (b ~ 'Resource *) => (b :: Concept bk) [1] (ie only Resource type of Concept) eg

-- Concept values
person = Entity "person"
name = Resource "name"
role = Role "father"

-- I want this to be valid
personHasName = Has person name

-- And this to be invalid
personHasRole = Has person role

[1] - After some reading of Constraints in Kinds, Type Families & Singleton Types, I guess it's possible to realise this kind of constraint via these principles. But I am completely at loss to make it work

Thanks to Cale at #haskel-beginners for suggesting this solution by introducing a phantom type and tagging the same in the Concept GADT

{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}

data ConceptType = EntityT | RoleT | RelationT | ResourceT | SubT ConceptType

data Concept (t :: ConceptType) a where
  Entity :: a -> Concept EntityT a
  Role :: a -> Concept RoleT a
  Relation :: a -> Concept RelationT a
  Resource :: a -> Concept ResourceT a
  Sub :: Concept t a -> Concept (SubT t) a

data Construct t a b where
  Has :: Concept t a -> Concept ResourceT b -> Construct t a b

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM