我有一个简单的ADT
data Concept a = Entity a | Role a | Relation a | Resource a | Sub (Concept a)
现在我想使用这个ADT创建一个GADT,它将限制它的构造函数的类型签名。这段代码不起作用,但我想做这样的事情:
data Construct a b where
Has :: Concept a -> 'Resource b -> Construct (Concept a) ('Resource b)
即。 Has
的{{1}}构造函数可以将第一个类型的参数作为任何形式的Construct
,但第二个类型参数应该是Concept
构造函数(提升为类型)。此签名失败,因为我使用类型代替类型。但是我想要意识到这样的事情并没有完全解决如何做同样的问题。
我正在导入Resource
。
编辑:
基于一条评论,如果我这样做
{-# LANGUAGE GADTs, TypeInType #-}
然后是类型检查。但是现在如何在 data Construct (a :: Concept ak) (b :: Concept bk) where
Has :: Construct a ('Resource b)
Has
我的要求是我想约束f :: Construct a b -> T.Text
f Has = ???
构造函数的类型,以便它只允许Has a b
(即任何概念)和a :: Concept ak
[1](即只有概念的资源类型) )例如
(b ~ 'Resource *) => (b :: Concept bk)
[1] - 在阅读了“种类中的约束”,“家庭类型”和“单身类型,我想通过这些原则可以实现这种约束。但我完全无法让它发挥作用
答案 0 :(得分:3)
感谢#haskel-beginners的Cale,通过引入幻像类型并在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