bhc-ast
Abstract syntax tree definitions for the Basel Haskell Compiler.
Overview
This crate defines the AST produced by parsing Haskell 2026 source code. The AST preserves source locations and syntactic structure, supporting the full range of Haskell syntax including GHC extensions.
Key Types
Module Structure
| Type |
Description |
Module |
A complete Haskell module |
ModuleName |
Qualified module name (Data.List) |
ImportDecl |
Import declaration with qualifiers and spec |
Export |
Export specification |
Pragma |
Language/compiler pragmas |
Declarations
| Type |
Description |
Decl |
Top-level declaration enum |
TypeSig |
Type signature (foo :: Int -> Int) |
FunBind |
Function binding with clauses |
DataDecl |
Data type declaration |
NewtypeDecl |
Newtype declaration |
TypeAlias |
Type synonym |
ClassDecl |
Type class definition |
InstanceDecl |
Type class instance |
ForeignDecl |
Foreign import/export |
FixityDecl |
Fixity declaration |
Expressions
| Type |
Description |
Expr |
Expression enum (30+ variants) |
Lit |
Literal values |
Alt |
Case alternative |
Stmt |
Do-notation statement |
FieldBind |
Record field binding |
Patterns
| Type |
Description |
Pat |
Pattern enum |
FieldPat |
Record field pattern |
Types
| Type |
Description |
Type |
Type expression |
TyVar |
Type variable |
Constraint |
Type class constraint |
Kind |
Kind expression |
Usage
use bhc_ast::{Module, Expr, Pat, Type, Decl};
let module: Module = parse_module(source)?;
for import in &module.imports {
println!("Importing: {}", import.module.to_string());
}
for decl in &module.decls {
match decl {
Decl::FunBind(fun) => {
println!("Function: {}", fun.name.name.as_str());
}
Decl::DataDecl(data) => {
println!("Data type: {}", data.name.name.as_str());
}
_ => {}
}
}
Expression Variants
pub enum Expr {
Var(Ident, Span), QualVar(ModuleName, Ident, Span), Con(Ident, Span), QualCon(ModuleName, Ident, Span), Lit(Lit, Span), App(Box<Expr>, Box<Expr>, Span), Lam(Vec<Pat>, Box<Expr>, Span), Let(Vec<Decl>, Box<Expr>, Span), If(Box<Expr>, Box<Expr>, Box<Expr>, Span), Case(Box<Expr>, Vec<Alt>, Span), Do(Vec<Stmt>, Span), Tuple(Vec<Expr>, Span), List(Vec<Expr>, Span), }
Pattern Variants
pub enum Pat {
Wildcard(Span), Var(Ident, Span), Lit(Lit, Span), Con(Ident, Vec<Pat>, Span), Infix(Box<Pat>, Ident, Box<Pat>, Span), Tuple(Vec<Pat>, Span), List(Vec<Pat>, Span), Record(Ident, Vec<FieldPat>, Span), As(Ident, Box<Pat>, Span), Lazy(Box<Pat>, Span), Bang(Box<Pat>, Span), }
Type Variants
pub enum Type {
Var(TyVar, Span), Con(Ident, Span), QualCon(ModuleName, Ident, Span), App(Box<Type>, Box<Type>, Span), Fun(Box<Type>, Box<Type>, Span), Tuple(Vec<Type>, Span), List(Box<Type>, Span), Forall(Vec<TyVar>, Box<Type>, Span), Constrained(Vec<Constraint>, Box<Type>, Span), Bang(Box<Type>, Span), Lazy(Box<Type>, Span), PromotedList(Vec<Type>, Span), NatLit(u64, Span), }
Language Extensions Supported
The AST supports many GHC extensions:
- Type System: GADTs, TypeFamilies, DataKinds, RankNTypes
- Syntax: LambdaCase, MultiWayIf, PatternGuards, ViewPatterns
- Strictness: BangPatterns, StrictData
- Deriving: DerivingVia, DerivingStrategies
- Records: RecordWildCards, NamedFieldPuns
- FFI: ForeignFunctionInterface
Typed Indices
The AST uses typed indices from bhc-index for efficient arena allocation:
use bhc_index::define_index;
define_index! {
pub struct ExprId;
pub struct PatId;
pub struct TypeId;
pub struct DeclId;
}
Design Notes
- All AST nodes carry
Span for source locations
- Names use
Symbol (interned) for efficient comparison
- Qualified names are represented explicitly
- The AST is syntax-oriented (desugaring happens in lowering)
Related Crates
bhc-span - Source locations
bhc-intern - Symbol interning for identifiers
bhc-index - Typed indices for arenas
bhc-parser - Produces AST from tokens
bhc-lower - Lowers AST to HIR