假设我有这样的类型(有效):
data WAE = Num Float
| Id String
| With [(String, WAE)] WAE -- This works, but I want to define it as below
deriving(Eq, Read, Show)
我想要这样的类型(不起作用):
data WAE = Num Float
| Id String
| With [(Id, WAE)] WAE -- This doesn't work ("Id not in scope")
deriving(Eq, Read, Show)
为什么我不能在 Haskell 中这样做?有没有实现类似效果的想法?
最佳答案
在 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
的东西是完全没问题的。
关于 haskell 数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7863420/