简体   繁体   English

数据构造函数不在Haskell范围内吗?

[英]data constructor not in the scope Haskell ?

here are the concerning data definition 这是有关的数据定义

data Decl = Decl Name Type

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

newtype Program = Program [FunDecl]

what i wanna do is to filter the [FunDecl] with the name of "main" 我想做的是用“ 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

but i get the error message of "Not in scope: data constructor 'Type'" how can i solve it ? 但是我收到错误消息“不在范围内:数据构造函数'类型'”,我该如何解决呢?

You appear to be confusing types/type constructors with variable names. 您似乎将类型/类型构造函数与变量名混淆了。 [Decl] is a type, and Decl is both a type constructor and a type ( data Decl = Decl ... ), so neither are valid variable names - you want to assign an identifier to the value you'll be passed (which is of type [Decl] ) so you need to use an identifier like decl1 for it (may be worth looking over this tutorial ). [Decl]是类型, Decl既是类型构造函数又是类型( data Decl = Decl ... ),因此都不是有效的变量名-您要为要传递的值分配一个标识符(的类型为[Decl] ),因此您需要使用类似decl1的标识符(可能值得阅读本教程 )。

Words beginning with an uppercase letter can only be types and type constructors - only words beginning with lowercase (and that aren't restricted) can be identifiers ( see this Q/A or the grammar specification ). 以大写字母开头的单词只能是类型和类型构造函数-只有以小写字母开头(且不受限制)的单词才能作为标识符( 请参阅此Q / A语法规范 )。


So you need to change your lambda: 因此,您需要更改lambda:

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

The FunDecl stays, as it's a type constructor that we're pattern matching against, where the identifiers given to the matched parts are called name , decl1 etc. FunDecl保留FunDecl ,因为它是我们要进行模式匹配的类型构造函数,匹配的部分的标识符称为namedecl1等。

Name is also changed to name in the lambda body so that we refer to the argument, not to the type constructor Name . 在lambda主体中, Name也更改为name ,以便我们引用参数,而不是类型构造函数Name


Given that you're only using the name argument, you can also define your lambda as: 假设您仅使用name参数,则还可以将lambda定义为:

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

Where _ is a "special" identifier which means "an argument that we don't want to give a name". 其中_是“特殊”标识符,表示“我们不想提供名称的参数”。 This is usually better practice. 这通常是更好的做法。

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

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