【问题标题】:Not in scope: data constructor in Haskell不在范围内:Haskell 中的数据构造函数
【发布时间】:2012-09-06 14:05:28
【问题描述】:

请告诉我是什么问题?

data Stack' v = Stack' [v] Int deriving (Show) ... 类型 StackInt = Stack' Int 主 = 打印(StackInt [1,2,3] 4)

我得到的错误是

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

怎么了?

【问题讨论】:

    标签: haskell


    【解决方案1】:

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

    data SomeType = SomeType Int
    

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

    :t SomeType
    SomeType :: Int -> SomeType
    

    现在,type 声明只是更长类型定义的简写,在您的情况下,使 StackInt 成为 Stack' Int 的同义词。但是为了构造这种类型的值,您仍然需要使用构造函数Stack'(其类型为[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)
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        没有名为Stackint 的数据构造函数。 Stackint 由您的 type 声明定义是一个 type 构造函数。

        对于Stack',数据构造函数是Stack',尽管由于类型同义词,它的类型为Int -> Stack' Int,而不是a -> Stack' a

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多