2016-11-30 67 views
-2

我想实现在Haskell如下:省略数据类型构造

0,1,2,...:N 
x,y,z,...:V 
+,*,-,/,...:F  
F alias for Expr -> Expr -> Expr 
Expr := N|V|F Expr Expr 

我的问题是第一:
是语法缺陷的类型级别?它有道理吗?所有的条款看起来像他们会检查(允许0,1,...既是Expr也是N子类型,并且x,y,...都是Expr和V子类型)。

其次,什么是最接近Haskell的实现?我目前的Haskell实现是:

data F = +|-|*|... 
data Expr = N|V|MakeExpr F Expr Expr 

有什么建议吗?

编辑 -

语法和实现之间的关键区别是类型构造器是隐含/在语法中省略。为什么Haskell中必须使用类型构造函数?

+1

这不是伪码 - 它只是一个语法。另外,我不确定你的意思是由'MakeExpr:F - > Expr - > Expr - >(Expr,Expr); MakeExpr f x y =(f,x,y)' - 'MakeExpr'已经在'data Expr = N | V | MakeExpr F Expr Expr'中定义。另外,您可能想要在“N”和“V”变体中记录实际值。无论如何,我不确定你在问什么。 – Alec

+0

修正后,现在应该更有意义了。 – dumb0

+0

构造函数不能以'+'等符号开头。考虑数据F = Plus |减| | DotDotDot'。 –

回答

2

语法和实现之间的关键区别是类型构造器是隐含/在语法中省略。为什么Haskell中必须使用类型构造函数?

在类型级别有缺陷的语法?是否有意义?所有的条款看起来像他们会检查类型(允许0,1,...既是Expr也是N子类型,并且x,y,...既是Expr也是V子类型

原因数据构造是强制性的Haskell是专门,以确保您不能有X,Y,......既Expr的和V亚型。

所以你的语法看起来像如何合理的模型你希望你的语言条款能够正常工作,但作为一个直接设计你没有任何意义来表达你的语言术语作为Haskell数据类型。

基本上,哈斯克尔故意没有亚型。它确保当您创建新类型(使用newtypedata)时,新类型的所有值都与所有其他现有类型(以及将来创建的所有类型)的值不同。它通过让用户定义类型的值始终出现在构造函数中(并且使其不可能“重用”构造函数;每当创建新类型时都会创建新的构造函数)来实现这一点。

Haskell的类型系统的工作方式依赖于这种缺乏亚型的。你可以设计一种允许子类型的语言(也许参见Scala)。但它从根本上不会是Haskell。

但你可以做什么,而不是定义是这样的:

data Expr 
    = ExprN N 
    | ExprV V 
    | ExprF Expr Expr 

你仍然不能有一个N价值,只是把它作为一个Expr。但你可以申请ExprN,然后你有一个Expr。而且,如果Haskell允许您使用N类型的n作为Expr,但它只是要求您添加一个类型注释,澄清这就是您的意思;你只需要说ExprN n而不是n :: Expr

同样,当你有一个Expr,并要在N将其应用功能,case语句中提取从ExprN构造的N(如果它的存在)是不是真的任何比你有更多的代码写来检查你的Expr是否实际上是N


类型构造函数”是在Haskell一个特定术语,这是不是我们在这里讨论的。我非常确定你的意思是“一种类型的构造函数”,但是如果你是偶尔使用这个术语来引用另一个东西的话,你会觉得很迂腐。

把它清除掉,如果你声明一个类像data Maybe a = Nothing | Just aNothingJust是新数据构造(其对“构造”极有可能意味着一个数据构造函数)和Maybe是一个新的类型构造