haskell 嵌套多参数类

dxxyhpgq  于 2022-11-14  发布在  其他
关注(0)|答案(1)|浏览(137)

我尝试在Haskell中定义一个新的数据类型,其中包含一个具有多个参数的数据类型(幻像类型):

newtype Dd x y z = ToDd Cudd.Cudd.DdNode deriving (Eq,Show)

data KnowStruct a b c =
  KnS Cudd.Cudd.DdManager [Prp] (Dd a b c) [(Agent,[Prp])]
  deriving (Eq,Show)

但这会给我一条错误消息:

• Expected kind ‘k0 -> k1 -> *’, but ‘Dd a’ has kind ‘*’
• In the type ‘(Dd a b c)’

为什么会这样呢?
是否也可以定义KnowStruct,而不使用所包含Dd类型的上下文/参数规范的任何要求?例如:

data KnowStruct =
  KnS Cudd.Cudd.DdManager [Prp] (Dd a b c) [(Agent,[Prp])]
  deriving (Eq,Show)

我创建了一个函数类来处理Dds的所有变体,并且只在作用于KnowStruct的函数中使用这些变体--所以理论上不需要指定KnowStruct包含什么类型的Dd。

vxbzzdmp

vxbzzdmp1#

第一种方法对我很有效,尝试给他们明确的类签名

{-# Language DerivingStrategies       #-}
{-# Language PolyKinds                #-}
{-# Language StandaloneKindSignatures #-}

import Data.Kind

data DdManager = DdManager deriving stock (Eq, Show)
data DdNode    = DdNode    deriving stock (Eq, Show)
data Agent     = Agent     deriving stock (Eq, Show)
data Prp       = Prp       deriving stock (Eq, Show)

type    Dd :: k -> j -> i -> Type
newtype Dd x y z = ToDd DdNode
  deriving stock (Eq, Show)

type KnowStruct :: k -> j -> i -> Type
data KnowStruct a b c =
  KnS DdManager [Prp] (Dd a b c) [(Agent,[Prp])]
  deriving stock (Eq, Show)

是否也可以定义KnowStruct,而不使用所包含的Dd类型的上下文/参数规范的任何要求?
这是可能的,并且被称为存在量化,因为类型变量不出现在返回类型中。
由于abc都是存在量化的,所以当你比较两个KnowStruct时,你是在比较Dd a1 b1 c1Dd a2 b2 c2与完全不同类型的变量。

{-# Language ExistentialQuantification #-}
{-# Language StandaloneDeriving        #-}

import Data.Kind

data DdManager = DdManager deriving stock (Eq, Show)
data DdNode    = DdNode    deriving stock (Eq, Show)
data Agent     = Agent     deriving stock (Eq, Show)
data Prp       = Prp       deriving stock (Eq, Show)

-- I specialize this to some kind (`Type'). Otherwise the
-- kind would have to be an argument to `KnowStruct` below.
type    Dd :: Type -> Type -> Type -> Type
newtype Dd x y z = ToDd DdNode
  deriving stock (Eq, Show)

type KnowStruct :: Type
data KnowStruct = forall a b c.
  KnS DdManager [Prp] (Dd a b c) [(Agent,[Prp])]

deriving stock
  instance Show KnowStruct

我更喜欢(等效的)GADT语法

{-# Language GADTs #-}

type KnowStruct :: Type
data KnowStruct where
  KnS :: DdManager -> [Prp] -> Dd a b c -> [(Agent,[Prp])] -> KnownStruct

相关问题