【问题标题】:data constructor not in the scope Haskell ?数据构造函数不在 Haskell 范围内?
【发布时间】:2018-03-27 17:31:07
【问题描述】:

这里是相关的数据定义

data Decl = Decl Name Type

data FunDecl = FunDecl Type Name [Decl] [Decl] Cmd

newtype Program = Program [FunDecl]

我想做的是用“main”的名称过滤[FunDecl]

filterByname :: Program -> Program
filterByname (Program p) =
  let p_main = filter (\FunDecl Type name [Decl] [Decl] cmd -> Name == "main") in Program $ p_main p

但我收到“不在范围内:数据构造函数‘类型’”的错误消息 我该如何解决?

【问题讨论】:

    标签: haskell constructor scope datalist


    【解决方案1】:

    您似乎将类型/类型构造函数与变量名混淆了。 [Decl] 是一种类型,Decl 既是类型构造函数又是类型 (data Decl = Decl ...),因此两者都不是有效的变量名 - 您想为将要传递的值分配一个标识符(它是输入[Decl]),所以你需要使用像decl1这样的标识符(可能值得查看this tutorial)。

    以大写字母开头的单词只能是类型和类型构造函数 - 只有以小写字母开头的单词(并且不受限制)可以是标识符(see this Q/Agrammar specification)。


    所以你需要改变你的 lambda:

    \(FunDecl declType name decl1 decl2 cmd) -> name == "main"
    

    FunDecl 保持不变,因为它是我们对其进行模式匹配的类型构造函数,其中匹配部分的标识符称为 namedecl1 等。

    Name 在 lambda 主体中也更改为 name,以便我们引用参数,而不是类型构造函数 Name


    鉴于您只使用 name 参数,您还可以将 lambda 定义为:

    \(FunDecl _ name _ _ _) -> name == "main"
    

    _ 是一个“特殊”标识符,表示“我们不想给出名称的参数”。这通常是更好的做法。

    【讨论】:

    • 非常感谢!我一直在思考这个问题好几个小时......作为一个新的haskell学习者
    • 但我遇到了另一个错误:构造函数“FunDecl”应该有 5 个参数,但是当我按照您的指示操作时没有给出任何参数
    • @ZheYuHe 哦,是的,我的错 - 您需要使用括号对数据构造函数进行分组,以便您的 lambda 接受一个参数,而不是 6 个单独的参数。查看我的编辑。
    • 昨天,我尝试了“\FunDecl (declType name decl1 decl2 cmd) -> name”使其符合要求,但失败了……现在看到你编辑后我终于明白了这种语法。谢谢!!
    猜你喜欢
    • 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
    相关资源
    最近更新 更多