Analyzing the ParseResult of haskell-src-extensions
The project I have proposed requires to analyze the source code in order to query the declared function matching certain conditions. Haskell-Src-Extensions has a parser in which we can get a data type which contains information about (the Module in) a Haskell (.hs) file. The porpose of this post is to analyze together the ParseResult of a Haskell (.hs) file. I have created two files that you could find here.
Main.hs: the parser.
Tutorial.hs: the file we are going to analyze.
We compile the program by doing
ghc -package ghc Main.hs
If we execute the program by doing
./Main.hs Tutorial.hs
The result will be the representation of a Module data type, which we can see in the following line:
Module (SrcLoc "Tutorial.hs" 1 1) (ModuleName "Tutorial") [] Nothing (Just []) [] [TypeSig (SrcLoc "Tutorial.hs" 3 1) [Ident "fib"] (TyFun (TyCon (UnQual (Ident "Integer"))) (TyCon (UnQual (Ident "Integer")))),FunBind [Match (SrcLoc "Tutorial.hs" 4 1) (Ident "fib") [PLit Signless (Int 0)] Nothing (UnGuardedRhs (Lit (Int 0))) (BDecls []),Match (SrcLoc "Tutorial.hs" 5 1) (Ident "fib") [PLit Signless (Int 1)] Nothing (UnGuardedRhs (Lit (Int 1))) (BDecls []),Match (SrcLoc "Tutorial.hs" 6 1) (Ident "fib") [PVar (Ident "n")] Nothing (UnGuardedRhs (InfixApp (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 1))))) (QVarOp (UnQual (Symbol "+"))) (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 2))))))) (BDecls [])]]
If we look at the declaration of the Module data type, we can see that it is:
Module SrcLoc ModuleName [ModulePragma] (Maybe WarningText) (Maybe [ExportSpec]) [ImportDecl] [Decl]
The definition is colored, so you can difference easily between the parameters. The [ModulePragma], the MaybeWarningText, the (Maybe [ExportSpec]) and [ImportDecl] doesn't have relevant information. But in the [Decl] parameter we have many information. We will make a "zoom" here.
...
Note: Forget colors above. Now we use different colors.
[TypeSig (SrcLoc "Tutorial.hs" 3 1) [Ident "fib"] (TyFun (TyCon (UnQual (Ident "Integer"))) (TyCon (UnQual (Ident "Integer")))),FunBind [Match (SrcLoc "Tutorial.hs" 4 1) (Ident "fib") [PLit Signless (Int 0)] Nothing (UnGuardedRhs (Lit (Int 0))) (BDecls []),Match (SrcLoc "Tutorial.hs" 5 1) (Ident "fib") [PLit Signless (Int 1)] Nothing (UnGuardedRhs (Lit (Int 1))) (BDecls []),Match (SrcLoc "Tutorial.hs" 6 1) (Ident "fib") [PVar (Ident "n")] Nothing (UnGuardedRhs (InfixApp (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 1))))) (QVarOp (UnQual (Symbol "+"))) (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 2))))))) (BDecls [])]]
This element is a list of declarations ([Decl]). Each element of this list, could represent the declaration of a type, a data type or a signature or a function, etc. In this case, the following declarations matches with:
fib :: Integer -> Integer fib 0 = 0 fib 1 = 1 fib n = fib (n - 1) + fib (n - 2)
1. The first element (-): It represents a signature. TypeSig 'contents' the following elements:
SrcLoc: the filepath of the source file.
[Ident ...]: the name of the signature or function
TyFun: says that this signature returns an Integer data type and receives an Integer data type, in this order.
2. The second element of the list (---): It represents the declaration of a function, in this case "fib". FunBind contents a list of Match which contents the following values: 2.1 First subelement, it makes reference to "fib 0 = 0".
SrcLoc: the filepath of the source file.
Ident ...: the name of the function
[PLit Signless (Int 0)]: the pattern, in this case is literal (constant) and it is 0.
Nothing
(UnGuardedRhs (Lit (Int 1))): this is the content in the body of the function, in this case it is only 1.
BDecls []: these are the declarations inside the function, for example, in where clauses (or in let clauses, too?)
2.2 Second subelement, it is pretty similar to 2.1, but parsing "fib 1 = 1"
2.1 Third subelement, it makes reference to "fib 0 = 0".
SrcLoc: the filepath of the source file.
Ident ...: the name of the function
[PVar (Ident "n")]: in this case the pattern is a variable and it is n.
Nothing
(UnGuardedRhs (InfixApp (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 1))))) (QVarOp (UnQual (Symbol "+"))) (App (Var (UnQual (Ident "fib"))) (Paren (InfixApp (Var (UnQual (Ident "n"))) (QVarOp (UnQual (Symbol "-"))) (Lit (Int 2))))))): here we can see that it is parsing the part of "fib (n - 1) + fib (n - 2)"
BDecls []: these are the declarations inside the function, for example, in where clauses.















