19

请告诉我是什么问题?

data Stack' v = Stack' [v] Int deriving (Show)
...
类型 StackInt = Stack' Int

主 = 打印(StackInt [1,2,3] 4)

我得到的错误是

不在范围内:数据构造函数“Stackint”

怎么了?

4

3 回答 3

32

在我看来,您混淆了类型和构造函数的概念,这是一个常见问题,因为它们位于不同的命名空间中并且通常具有相同的名称。在 Haskell 表达式中

data SomeType = SomeType Int

比如说,您实际上是在定义类型SomeType构造函数 SomeType。类型不是正常意义上的函数,但构造函数是。如果你向 ghci 询问 SomeType 的类型,你会得到:

:t SomeType
SomeType :: Int -> SomeType

现在,type声明只是更长类型定义的简写,在您的情况下,StackInt它是Stack' Int. 但是为了构造这种类型的值,您仍然需要使用构造函数Stack'(它具有 type [v] -> Int -> Stack' v)。所以你的代码应该是

data Stack' v = Stack' [v] Int deriving (Show)

main = print(Stack' [1,2,3] 4)

如果您想确定类型是,Stack' Int那么您可以添加一个函数

data Stack' v = Stack' [v] Int deriving (Show)

stackInt :: [Int] -> Int -> Stack' Int
stackInt list i = Stack' list i

main = print(stackInt [1,2,3] 4)

编辑:不是我在stackInt list i = Stack' list i这里写的透明度,但你可以写得更优雅,就像stackInt = Stack'. 类型约束确保您在此处获得正确的类型。

如果需要,您还可以同时拥有新功能和类型同义词,即

data Stack' v = Stack' [v] Int deriving (Show)
type StackInt = Stack' Int

stackInt :: [Int] -> Int -> StackInt
stackInt list i = Stack' list i

main = print(stackInt [1,2,3] 4)
于 2012-09-06T14:18:50.020 回答
16

构造函数的名称是Stack',不是StackInt。创建类型别名 usingtype不会为构造函数创建别名(这没有意义,因为该类型可能有许多构造函数,并且它们的名称根本不必与类型名称相关)。

于 2012-09-06T14:10:44.437 回答
2

没有调用数据构造函数Stackint。如您的声明Stackint所定义的是类型构造函数。type

数据构造函数是 , Stack'Stack'尽管由于类型同义词,它会有 typeInt -> Stack' Int而不是a -> Stack' a.

于 2012-09-06T14:14:12.423 回答