Haskell数据类型

Haskell数据类型,haskell,types,Haskell,Types,假设我有一个这样的类型(有效): 我想要这样的类型(不起作用): 为什么我不能在Haskell这样做?有没有达到类似效果的想法?这里: | With [(Id, WAE)] WAE 您正在预期类型的上下文中使用数据构造函数Id。Id的类型是WAE,因此如果您将此行更改为: | With [(WAE, WAE)] WAE 它将编译,但结果可能不是您想要的 如果您只想显示所讨论的字符串在语义上是标识符,则可以使用类型别名: type Id = String data WAE

假设我有一个这样的类型(有效):

我想要这样的类型(不起作用):

为什么我不能在Haskell这样做?有没有达到类似效果的想法?

这里:

     | With [(Id, WAE)] WAE
您正在预期类型的上下文中使用数据构造函数
Id
Id
的类型是
WAE
,因此如果您将此行更改为:

     | With [(WAE, WAE)] WAE
它将编译,但结果可能不是您想要的

如果您只想显示所讨论的字符串在语义上是标识符,则可以使用类型别名:

type Id = String

data WAE = Num Float
         | Id Id
         | With [(Id, WAE)] WAE
         deriving(Eq, Read, Show)

根据你的问题,我不完全确定你想要完成什么。以下是Haskell类型系统的两种可能性

data WAE = Num Float
         | Id String
         | With [(WAE, WAE)] WAE
         deriving (Eq, Read, Show)
但是,我不确定这是否是您想要的,因为它允许在配对的第一部分中使用不止一个id

另一种可能是为id创建新类型(或别名),如下所示:

data MyId = MyId String deriving (Eq, Read, Show)
data WAE = Num MyId Float
         | Id MyId
         | With [(MyId, WAE)] WAE 
         deriving (Eq, Read, Show)
请注意,MyId也可以使用
newtype
type
创建,每种类型的含义略有不同


但是,您不能使用
Id
,因为它是一个数据构造函数,其中需要一个类型。

在Haskell中,有两个不同的名称空间。一个用于值,一个用于类型。诸如
Id
之类的数据构造函数位于值命名空间中,而诸如
String
之类的类型构造函数以及类位于类型命名空间中。这是可以的,因为不存在允许两者同时存在的上下文

在数据类型的定义中,这两个名称空间并排存在,因为您在定义一个新的类型构造函数和几个新的数据构造函数,同时引用现有的类型构造函数

data WAE = Num Float
         | Id String
         | With [(String, WAE)] WAE
         deriving(Eq, Read, Show)
这里,
WAE
Float
String
(,)
[]
Eq
Read
Show
都是类型世界中的名称,而
Num
Id
With
则是值世界中的名称。混合它们没有任何意义,这就是为什么
Id
不在第二段代码的范围内,因为您在类型上下文中,并且没有称为
Id
的类型级别的东西

你的问题并不是100%清楚你想做什么,但我怀疑可能是这样的:

type Id = String   -- Or perhaps a newtype
data WAE = Num Float
         | Id Id
         | With [(Id, WAE)] WAE
         deriving(Eq, Read, Show)

请注意,因为名称空间是不同的,所以在这两个名称空间中都有一个名为
Id
的东西是非常好的。

好的。我可以使用一个字符串,但由于该字符串实际上是一个“Id”(语义上),我认为展示它是有意义的。我认为xcross想要的一般模式是将代数数据类型中的递归限制为特定的构造函数,而不是“整体”类型。你不能用普通的代数类型来做这件事,但也许你可以用GADTs来做。。。;数据WAE=…|Id |…和您的名称冲突。这就是为什么在构造函数的后缀中加上所构造类型的缩写是很常见的。
data WAE = Num Float
         | Id String
         | With [(String, WAE)] WAE
         deriving(Eq, Read, Show)
type Id = String   -- Or perhaps a newtype
data WAE = Num Float
         | Id Id
         | With [(Id, WAE)] WAE
         deriving(Eq, Read, Show)