简体   繁体   English

不在范围内:Haskell中的数据构造函数

[英]Not in scope: data constructor in Haskell

Please tell me what is the problem? 请告诉我有什么问题?

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

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

The error i am getting is 我得到的错误是

Not in scope: data constructor `Stackint'

What is wrong? 怎么了?

It looks to me like you are confusing the concepts of types and constructors, this is a common problem as they live in separate namespaces and are often given the same name. 在我看来,你混淆了类型和构造函数的概念,这是一个常见问题,因为它们存在于不同的命名空间中,并且通常具有相同的名称。 In the Haskell expression 在Haskell表达式中

data SomeType = SomeType Int

say, you are actually defining the type SomeType and a constructor SomeType . 比如说,您实际上是在定义SomeType类型和构造函数 SomeType The type is not a function in the normal sense, but the constructor is. 类型不是正常意义上的函数,但构造函数是。 If you asked ghci for the type of SomeType you would get this: 如果您向ghci询问SomeType的类型,您会得到:

:t SomeType
SomeType :: Int -> SomeType

Now, a type declaration is just a shorthand for a longer type definition, in your case making StackInt a synonym of Stack' Int . 现在,一个type的声明仅仅是一个较长的类型定义的简写,你的情况做StackInt的代名词Stack' Int But in order to construct a value of this type you still need to use the constructor Stack' (which has type [v] -> Int -> Stack' v ). 但是为了构造这种类型的值,你仍然需要使用构造函数Stack' (其类型为[v] -> Int -> Stack' v )。 So your code should be 所以你的代码应该是

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

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

If you wanted to be sure that the type was Stack' Int then you could add a function 如果你想确定类型是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)

EDIT: Not also that I've written stackInt list i = Stack' list i for transparency here, but you can write it more elegantly just as stackInt = Stack' . 编辑:还不是我写了stackInt list i = Stack' list i的透明度这里,但你可以写得更优雅,就像stackInt = Stack' It is the type constraint that makes sure that you get the right type here. 这是类型约束,可确保您在此处获得正确的类型。

You could also have both the new function and the type synonym if you wanted, ie 如果需要,您也可以同时拥有新函数和类型同义词,即

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)

The name of the constructor is Stack' , not StackInt . 构造函数的名称是Stack' ,而不是StackInt Creating a type alias using type does not create an alias for the constructors (which wouldn't make sense since there may be many constructors for the type and their names don't have to be related the type name at all). 使用type创建类型别名不会为构造函数创建别名(这是没有意义的,因为类型可能有许多构造函数,它们的名称根本不必与类型名称相关)。

There is no data constructor called Stackint . 没有名为Stackint数据构造Stackint Stackint as defined by your type declaration is a type constructor. type声明定义的Stackint是一个类型构造函数。

The data constructor is, as for Stack' , Stack' , although thanks to the type synonym it'll have type Int -> Stack' Int instead of a -> Stack' a . 数据构造函数与Stack'Stack' ,虽然由于类型同义词,它将具有类型Int -> Stack' Int而不是a -> Stack' a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM