haskell-GADTs构造函数

haskell-GADTs构造函数,haskell,gadt,Haskell,Gadt,我有以下几点 data Expr = Condition v | And Expr Expr | Or Expr Expr 我要求考虑下面的非类型化版本以完成: data Expr e where 我不确定我应该为构造函数写些什么。我尝试了以下方法: data Expr e where Condition :: v -> Expr v And :: -- really not sure what to do with this one

我有以下几点

data Expr = Condition v
          | And Expr Expr
          | Or Expr Expr

我要求考虑下面的非类型化版本以完成:

data Expr e where
我不确定我应该为构造函数写些什么。我尝试了以下方法:

data Expr e where
  Condition :: v -> Expr v
  And :: -- really not sure what to do with this one
  OR :: Expr b -> (Expr b -> Expr a) -> Maybe Expr a -> Expr b
此外,由于
v
可以是任何类型,即
int
bool
等,因此可以将其命名为以下(上文)并稍后声明
v
的类型吗

data v = IntVat int
任何帮助都将不胜感激:)

编辑:根据我对练习的理解,更改了整个帖子,增加了一点信息和清晰度


基本上,我需要帮助找出GADT的构造函数,以
data Expr=Condition v…etc
作为参考。

这听起来像是一种存在类型。我必须承认,我从来没有真正使用过它们,我只是试图理解它们;不管怎样,也许它的意思是这样的:

data Expr = forall v. Condition v
          | And Expr Expr
          | Or Expr Expr
然后你有了这样一个GADT(他们概括了存在主义,参见):

虽然,这(就我理解的概念而言)没有多大意义,因为你不能用
v
做任何事情

另一方面,这(我希望)更有意义(因为有一个“条件”):

然后你可以做,例如

eval :: Expr -> Bool
eval (Condition v) = test v
eval (And e1 e2) = (eval e1) && (eval e2)
eval (Or e1 e2) = (eval e1) || (eval e2)
这将适用于不同类型的“条件”


不过,我没有测试这段代码,而且,正如我所说,我并不是存在主义的专业人士。我希望我的代码是正确的,但请告诉我任何人,如果你知道得更好(或者我完全错了…)

这听起来像是一种存在类型。我必须承认,我从来没有真正使用过它们,我只是试图理解它们;不管怎样,也许它的意思是这样的:

data Expr = forall v. Condition v
          | And Expr Expr
          | Or Expr Expr
然后你有了这样一个GADT(他们概括了存在主义,参见):

虽然,这(就我理解的概念而言)没有多大意义,因为你不能用
v
做任何事情

另一方面,这(我希望)更有意义(因为有一个“条件”):

然后你可以做,例如

eval :: Expr -> Bool
eval (Condition v) = test v
eval (And e1 e2) = (eval e1) && (eval e2)
eval (Or e1 e2) = (eval e1) || (eval e2)
这将适用于不同类型的“条件”


不过,我没有测试这段代码,而且,正如我所说,我并不是存在主义的专业人士。我希望我的代码是正确的,但请告诉我任何人,如果你知道得更好(或者我完全错了…

如果我在GADT上设置作业,使用基本表达语言作为激励示例,下面是我想要的答案:

data Expr v where
    Literal :: v -> Expr v
    And     :: Expr Bool -> Expr Bool -> Expr Bool
    Or      :: Expr Bool -> Expr Bool -> Expr Bool
    -- and I'd probably add some things like this to
    -- show why the type variable is useful
    Equal   :: Expr Int -> Expr Int -> Expr Bool
    If      :: Expr Bool -> Expr v -> Expr v -> Expr v
您可以看到为什么您可以将其称为“类型化”表达式:类型变量的实例化看起来像小型语言的类型化规则:

a : Bool         b : Bool
-------------------------
    And a b : Bool

a : Int          b : Int
------------------------
    Equal a b : Bool

等等。

如果我用一种基本的表达语言作为激励性的例子,在GADT上设置一个作业,下面是我想要的答案:

data Expr v where
    Literal :: v -> Expr v
    And     :: Expr Bool -> Expr Bool -> Expr Bool
    Or      :: Expr Bool -> Expr Bool -> Expr Bool
    -- and I'd probably add some things like this to
    -- show why the type variable is useful
    Equal   :: Expr Int -> Expr Int -> Expr Bool
    If      :: Expr Bool -> Expr v -> Expr v -> Expr v
您可以看到为什么您可以将其称为“类型化”表达式:类型变量的实例化看起来像小型语言的类型化规则:

a : Bool         b : Bool
-------------------------
    And a b : Bool

a : Int          b : Int
------------------------
    Equal a b : Bool

等等。

与GADT声明相比,
Expr
的非GADT声明没有参数,这是故意的吗?@dbaupp我这么说,因为这是为了练习而给我的。
V
不是一个类型变量(在第一个定义中),因为它是大写的,它必须引用特定的类型,对吗?@Peter oh抱歉,它的小写字母难道你的第一个代码不应该是‘data Expr v=Condition v |和(Expr v)(Expr v)|或(Expr v)(Expr v)’吗?
Expr
的非GADT声明没有参数(与GADT声明相反),这是故意的吗?@dbaupp我会这么说,因为这是为了练习而给我的。
v
不是一个类型变量(在第一个定义中),因为它的大写字母必须指特定的类型,对吗?@Peter oh抱歉,它的小写字母不应该是“data Expr v=Condition v”和(Expr v)(Expr v)或(Expr v)(Expr v)”?
data Expr
Expr
Expr
的非类型版本,因为存在(带forall)是“非类型化"但是,它可以存储不同的类型,这些类型稍后可以通过模式匹配构造函数来访问。另外,我同意gfour的观点,保留那些
v
s可能是一个错误。添加它们将导致一个正常的、类似树的递归类型。
dataexpr
是作为存在的
Expr
Expr
(带forall)是“非类型化的”但是,它可以存储不同的类型,这些类型稍后可以通过模式匹配构造函数来访问。另外,我同意gfour的观点,保留那些
v
s可能是一个错误。添加它们将导致一个正常的、类似树的递归类型。