数据构造函数不在 Haskell 范围内?
data constructor not in the scope Haskell ?
这里是相关的数据定义
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
但我收到 "Not in scope: data constructor ‘Type’" 的错误消息
我该如何解决?
您似乎混淆了 types/type 构造函数和变量名。 [Decl]
是一种类型,而 Decl
既是类型构造函数又是类型 (data Decl = Decl ...
),因此两者都不是有效的变量名 - 您想要为要分配的值分配一个标识符被传递(类型为 [Decl]
),因此您需要为其使用像 decl1
这样的标识符(可能值得查看 this tutorial)。
以大写字母开头的单词只能是类型和类型构造函数 - 只有以小写字母开头(且不受限制)的单词可以是标识符 (see this Q/A or the grammar specification)。
所以你需要改变你的 lambda:
\(FunDecl declType name decl1 decl2 cmd) -> name == "main"
FunDecl
保留,因为它是我们要进行模式匹配的类型构造函数,其中为匹配部分指定的标识符称为 name
、decl1
等
Name
在 lambda 主体中也更改为 name
以便我们引用参数,而不是类型构造函数 Name
.
鉴于您只使用 name
参数,您还可以将 lambda 定义为:
\(FunDecl _ name _ _ _) -> name == "main"
其中 _
是一个 "special" 标识符,表示 "an argument that we don't want to give a name"。这通常是更好的做法。
这里是相关的数据定义
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
但我收到 "Not in scope: data constructor ‘Type’" 的错误消息 我该如何解决?
您似乎混淆了 types/type 构造函数和变量名。 [Decl]
是一种类型,而 Decl
既是类型构造函数又是类型 (data Decl = Decl ...
),因此两者都不是有效的变量名 - 您想要为要分配的值分配一个标识符被传递(类型为 [Decl]
),因此您需要为其使用像 decl1
这样的标识符(可能值得查看 this tutorial)。
以大写字母开头的单词只能是类型和类型构造函数 - 只有以小写字母开头(且不受限制)的单词可以是标识符 (see this Q/A or the grammar specification)。
所以你需要改变你的 lambda:
\(FunDecl declType name decl1 decl2 cmd) -> name == "main"
FunDecl
保留,因为它是我们要进行模式匹配的类型构造函数,其中为匹配部分指定的标识符称为 name
、decl1
等
Name
在 lambda 主体中也更改为 name
以便我们引用参数,而不是类型构造函数 Name
.
鉴于您只使用 name
参数,您还可以将 lambda 定义为:
\(FunDecl _ name _ _ _) -> name == "main"
其中 _
是一个 "special" 标识符,表示 "an argument that we don't want to give a name"。这通常是更好的做法。