Reputation: 25
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"
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 ?
Upvotes: 0
Views: 343
Reputation: 6037
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).
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).
So you need to change your 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.
Name
is also changed to name
in the lambda body so that we refer to the argument, not to the type constructor Name
.
Given that you're only using the name
argument, you can also define your lambda as:
\(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.
Upvotes: 2