Glasgow Haskell Compiler
View on Wikipedia
| The Glasgow Haskell Compiler | |
|---|---|
| Original author | Kevin Hammond |
| Developers | Simon Marlow, Simon Peyton Jones, The Glasgow Haskell Team[1] |
| Initial release | December 1992[2] |
| Stable release | 9.12.1 |
| Repository | |
| Written in | Haskell, C |
| Operating system | Linux, macOS 10.7 and later, Windows Vista and later, FreeBSD[4] |
| Platform | x86 (linux only)[4], x86-64[5], AArch64 |
| Available in | English |
| Type | Compiler |
| License | BSD 3-clause (new) |
| Website | www |
The Glasgow Haskell Compiler (GHC) is a native or machine code compiler for the functional programming language Haskell.[6] It provides a cross-platform software environment for writing and testing Haskell code and supports many extensions, libraries, and optimisations that streamline the process of generating and executing code. GHC is the most commonly used Haskell compiler.[7] It is free and open-source software released under a BSD license.
History
[edit]GHC originally begun in 1989 as a prototype, written in Lazy ML (LML) by Kevin Hammond at the University of Glasgow. Later that year, the prototype was completely rewritten in Haskell, except for its parser, by Cordelia Hall, Will Partain, and Simon Peyton Jones. Its first beta release was on 1 April 1991. Later releases added a strictness analyzer and language extensions such as monadic I/O, mutable arrays, unboxed data types, concurrent and parallel programming models (such as software transactional memory and data parallelism) and a profiler.[2]
Peyton Jones, and Marlow, later moved to Microsoft Research in Cambridge, where they continued to be primarily responsible for developing GHC. GHC also contains code from more than three hundred other contributors.[1] From 2009 to about 2014, third-party contributions to GHC were funded by the Industrial Haskell Group.[8]
GHC names
[edit]Since early releases the official website[9] has referred to GHC as The Glasgow Haskell Compiler, whereas in the executable version command it is identified as The Glorious Glasgow Haskell Compilation System.[10] This has been reflected in the documentation.[11] Initially, it had the internal name of The Glamorous Glasgow Haskell Compiler.[12]
Architecture
[edit]GHC is written in Haskell,[13] but the runtime system for Haskell, essential to run programs, is written in C and C--.
GHC's front end, incorporating the lexer, parser and typechecker, is designed to preserve as much information about the source language as possible until after type inference is complete, toward the goal of providing clear error messages to users.[2] After type checking, the Haskell code is desugared into a typed intermediate language known as "Core" (based on System F, extended with let and case expressions). Core has been extended to support generalized algebraic datatypes in its type system, and is now based on an extension to System F known as System FC.[14]
In the tradition of type-directed compiling, GHC's simplifier, or "middle end", where most of the optimizations implemented in GHC are performed, is structured as a series of source-to-source transformations on Core code. The analyses and transformations performed in this compiler stage include demand analysis (a generalization of strictness analysis), application of user-defined rewrite rules (including a set of rules included in GHC's standard libraries that performs foldr/build fusion), unfolding (called "inlining" in more traditional compilers), let-floating, an analysis that determines which function arguments can be unboxed, constructed product result analysis, specialization of overloaded functions, and a set of simpler local transformations such as constant folding and beta reduction.[15]
The back end of the compiler transforms Core code into an internal representation of C--, via an intermediate language STG (short for "Spineless Tagless G-machine").[16] The C-- code can then take one of three routes: it is either printed as C code for compilation with GCC, converted directly into native machine code (the traditional "code generation" phase), or converted to LLVM IR for compilation with LLVM. In all three cases, the resultant native code is finally linked against the GHC runtime system to produce an executable.
Language
[edit]GHC complies with the language standards, both Haskell 98[17] and Haskell 2010.[18] It also supports many optional extensions to the Haskell standard: for example, the software transactional memory (STM) library, which allows for Composable Memory Transactions.
Extensions to Haskell
[edit]Many extensions to Haskell have been proposed. These provide features not described in the language specification, or they redefine existing constructs. As such, each extension may not be supported by all Haskell implementations. There is an ongoing effort[19] to describe extensions and select those which will be included in future versions of the language specification.
The extensions[20] supported by the Glasgow Haskell Compiler include:
- Unboxed types and operations. These represent the primitive datatypes of the underlying hardware, without the indirection of a pointer to the heap or the possibility of deferred evaluation. Numerically intensive code can be significantly faster when coded using these types.
- The ability to specify strict evaluation for a value, pattern binding, or datatype field.
- More convenient syntax for working with modules, patterns, list comprehensions, operators, records, and tuples.
- Syntactic sugar for computing with arrows and recursively defined monadic values. Both of these concepts extend the monadic do-notation provided in standard Haskell.
- A significantly more powerful system of types and typeclasses, described below.
- Template Haskell, a system for compile-time metaprogramming. Expressions can be written to produce Haskell code in the form of an abstract syntax tree. These expressions are typechecked and evaluated at compile time; the generated code is then included as if it were part of the original code. Together with the ability to reflect on definitions, this provides a powerful tool for further extensions to the language.
- Quasi-quotation, which allows the user to define new concrete syntax for expressions and patterns. Quasi-quotation is useful when a metaprogram written in Haskell manipulates code written in a language other than Haskell.
- Generic typeclasses, which specify functions solely in terms of the algebraic structure of the types they operate on.
- Parallel evaluation of expressions using multiple CPU cores. This does not require explicitly spawning threads. The distribution of work happens implicitly, based on annotations provided in the program.
- Compiler pragmas for directing optimizations such as inline expansion and specializing functions for particular types.
- Customizable rewrite rules are rules describing how to replace one expression with an equivalent, but more efficiently evaluated expression. These are used within core data structure libraries to improve performance throughout application-level code.[21]
- Record dot syntax. Provides syntactic sugar for accessing the fields of a (potentially nested) record which is similar to the syntax of many other programming languages.[22]
Type system extensions
[edit]An expressive static type system is one of the major defining features of Haskell. Accordingly, much of the work in extending the language has been directed towards data types and type classes.
The Glasgow Haskell Compiler supports an extended type system based on the theoretical System FC.[14] Major extensions to the type system include:
- Arbitrary-rank and impredicative polymorphism. Essentially, a polymorphic function or datatype constructor may require that one of its arguments is also polymorphic.
- Generalized algebraic data types. Each constructor of a polymorphic datatype can encode information into the resulting type. A function which pattern-matches on this type can use the per-constructor type information to perform more specific operations on data.
- Existential types. These can be used to "bundle" some data together with operations on that data, in such a way that the operations can be used without exposing the specific type of the underlying data. Such a value is very similar to an object as found in object-oriented programming languages.
- Data types that do not actually contain any values. These can be useful to represent data in type-level metaprogramming.
- Type families: user-defined functions from types to types. Whereas parametric polymorphism provides the same structure for every type instantiation, type families provide ad hoc polymorphism with implementations that can differ between instantiations. Use cases include content-aware optimizing containers and type-level metaprogramming.
- Implicit function parameters that have dynamic scope. These are represented in types in much the same way as type class constraints.
- Linear types (GHC 9.0)
Extensions relating to type classes include:
- A type class may be parametrized on more than one type. Thus a type class can describe not only a set of types, but an n-ary relation on types.
- Functional dependencies, which constrain parts of that relation to be a mathematical function on types. That is, the constraint specifies that some type class parameter is completely determined once some other set of parameters is fixed. This guides the process of type inference in situations where otherwise there would be ambiguity.
- Significantly relaxed rules regarding the allowable shape of type class instances. When these are enabled in full, the type class system becomes a Turing-complete language for logic programming at compile time.
- Type families, as described above, may also be associated with a type class.
- The automatic generation of certain type class instances is extended in several ways. New type classes for generic programming and common recursion patterns are supported. Also, when a new type is declared as isomorphic to an existing type, any type class instance declared for the underlying type may be lifted to the new type "for free".
Portability
[edit]Versions of GHC are available for several system or computing platform, including Windows and most varieties of Unix (such as Linux, FreeBSD, OpenBSD, and macOS).[23] GHC has also been ported to several different processor architectures.[23]
See also
[edit]References
[edit]- ^ a b "The GHC Team". Haskell.org. Retrieved 1 September 2016.
- ^ a b c Hudak, P.; Hughes, J.; Peyton Jones, S.; Wadler, P. (June 2007). "A History of Haskell: Being Lazy With Class" (PDF). Procedures of the Third ACM SIGPLAN History of Programming Languages Conference (HOPL-III). Retrieved 1 September 2016.
- ^ "Download – The Glasgow Haskell Compiler". Haskell.org.
- ^ a b "Download Version 9.12.2 (released 14th Mar 2025)". GHC Team.
- ^ "Deprecation of 32-bit Darwin and Windows platforms". GHC Team.
- ^ "The Glorious Glasgow Haskell Compilation System User's Guide". Haskell.org. Retrieved 27 July 2014.
- ^ "2017 state of Haskell survey results". taylor.fausak.me. 15 November 2017. Retrieved 11 December 2017.
- ^ "Industrial Haskell Group". Haskell.org. 2014. Retrieved 1 September 2016.
- ^ "GHC The Glasgow Haskell Compiler". Haskell.org. Retrieved 14 January 2022.
- ^ "Repository: configure.ac". gitlab.haskell.org. 12 January 2022. Retrieved 14 January 2022.
- ^ "The Glorious Glasgow Haskell Compilation System User's Guide, Version 7.6.3". downloads.haskell.org. Retrieved 14 January 2022.
- ^ "ghc-0.29-src.tar.gz" (tar gzip). downloads.haskell.org. File: ghc-0.29/ghc/PATCHLEVEL. Retrieved 14 January 2022.
- ^ "GHC Commentary: The Compiler". Haskell.org. 23 March 2016. Archived from the original on 23 March 2016. Retrieved 26 May 2016.
- ^ a b Sulzmann, M.; Chakravarty, M. M. T.; Peyton Jones, S.; Donnelly, K. (January 2007). "System F with Type Equality Coercions". Procedures of the ACM Workshop on Types in Language Design and Implementation (TLDI).
- ^ Peyton Jones, S. (April 1996). "Compiling Haskell by program transformation: a report from the trenches". Procedures of the European Symposium on Programming (ESOP).
- ^ Peyton Jones, S. (April 1992). "Implementing lazy functional languages on stock hardware: the Spineless Tagless G-machine, Version 2.5". Journal of Functional Programming. 2 (2): 127–202. doi:10.1017/S0956796800000319.
- ^ "Haskell 98 Language and Libraries: The Revised Report". Haskell.org. Retrieved 28 January 2007.
- ^ "Haskell 2010 Language Report". Haskell.org. Retrieved 30 August 2012.
- ^ "Welcome to Haskell' (Haskell Prime)". Haskell.org. Archived from the original on 20 February 2016. Retrieved 26 May 2016.
- ^ "GHC Language Features". Haskell.org. Archived from the original on 29 June 2016. Retrieved 25 May 2016.
- ^ Coutts, D.; Leshchinskiy, R.; Stewart, D. (April 2007). "Stream Fusion: From Lists to Streams to Nothing at All". Procedures of the ACM SIGPLAN International Conference on Functional Programming (ICFP). Archived from the original on 23 September 2007.
- ^ Mitchell, Neil; Fletcher, Shayne (3 May 2020). "Record Dot Syntax". ghc-proposals. GitHub. Retrieved 30 June 2020.
- ^ a b Platforms at gitlab.haskell.org
External links
[edit]Glasgow Haskell Compiler
View on GrokipediaOverview
Description
The Glasgow Haskell Compiler (GHC) is an open-source native code compiler for the Haskell programming language, originally developed at the University of Glasgow starting in January 1989.[4] Haskell is a standardized, general-purpose, purely functional programming language characterized by lazy evaluation, where expressions are evaluated only when needed, enabling referential transparency and immutability as core principles.[5] GHC serves as the de facto standard implementation of Haskell, supporting the Haskell 2010 language standard while providing extensive extensions for advanced features.[6] GHC's primary functionalities include compiling Haskell source code into standalone executable binaries for various platforms, often leveraging optimizations for high performance. It also offers an interactive mode via GHCi, allowing developers to evaluate expressions, load modules, and debug code in real time. Additionally, GHC generates intermediate representations such as Core, a simplified functional language, which facilitates analysis, optimization, and integration with other tools in the Haskell ecosystem. The compiler's first public beta release occurred on April 1, 1991, marking an early milestone in its evolution from an academic project to a robust tool.[4] Today, GHC plays a pivotal role in academia for advancing functional programming research, including type systems and optimization techniques, and in industry for building reliable, concurrent systems in domains like finance and aerospace.[2][7]Licensing and Availability
The Glasgow Haskell Compiler (GHC) is released under the BSD 3-clause license, a permissive open-source license that allows users to freely use, modify, and distribute the software, provided they retain the original copyright notice, conditions, and disclaimer in all copies or substantial portions of the software.[8] This licensing framework has been in effect since 2007, succeeding earlier custom license terms that were revised to facilitate wider adoption and integration within the open-source ecosystem.[9] GHC is publicly available through official downloads on the Haskell website, offering pre-built binary packages tailored for major operating systems and architectures such as Linux (x86_64 and AArch64), macOS (x86_64 and ARM64), Windows (x86_64), and others including FreeBSD.[1] The complete source code resides in a GitLab repository, which has hosted the project since its migration from earlier version control systems in December 2018, enabling developers to clone, fork, and submit contributions via merge requests.[10] Users can install GHC via straightforward binary installers provided in the downloads, which include platform-specific setup scripts and integrate GHC with tools like the interactive environment GHCi.[1] Alternatively, package managers simplify the process: on macOS, Homebrew users can runbrew install ghc to fetch and configure the latest stable version; on Windows, Chocolatey supports installation with choco install ghc, handling dependencies automatically.[11][12] For advanced users preferring customization, building GHC from source is supported on POSIX-compliant systems, requiring a bootstrapping GHC installation (version 9.0.1 or later) and external dependencies such as the lexical analyzer tool Alex (version 3.2.6 or later), the parser generator Happy (version 1.19.9 or later), GCC or Clang, GNU Make, Python, and autotools like Autoconf and Automake; comprehensive build instructions outline platform-specific prerequisites and compilation steps.[13][14]
Distributing GHC derivatives, modified versions, or contributions must comply with the BSD 3-clause terms, which prohibit the use of the University of Glasgow's or contributors' names for endorsement or promotion without prior written permission, while ensuring the license notice accompanies all redistributions to maintain transparency and legal clarity.[8]
History
Origins and Early Development
The Glasgow Haskell Compiler (GHC) was founded in January 1989 at the University of Glasgow as part of the broader effort to implement the newly designed Haskell programming language, which sought to standardize non-strict, purely functional programming following the Haskell 1.0 report published in April 1990.[4] This initiative emerged from the need for an efficient, portable compiler to demonstrate the viability of lazy evaluation in Haskell, a feature that delayed computation until values were required, enabling more expressive and modular code compared to earlier strict languages.[4] Prior implementations like Lazy ML (LML) from Chalmers University, a lazy functional language with efficient graph reduction via the G-machine, and Yale Haskell, a lazy but less community-oriented effort led by Paul Hudak, highlighted the demand for a robust, optimizing Haskell compiler to support research and practical applications.[4][15] Early development involved a core team of researchers focused on creating a prototype to validate Haskell's design, with Kevin Hammond leading the initial implementation in LML as a front-end to the Chalmers LML compiler, achieving functionality by June 1989 and incorporating Haskell 1.0 features like type classes.[4] Simon Peyton Jones joined the project in autumn 1989, alongside Cordelia Hall and Will Partain, bringing expertise in functional language implementation; Peyton Jones would go on to lead GHC's development until 2019.[4] Additional key contributors included Lennart Augustsson from Chalmers, who contributed to Haskell's committee and later developed the HBC compiler, as well as collaborators from Yale such as Paul Hudak and from Edinburgh like Philip Wadler, reflecting the multi-institutional ties that drove Haskell's creation.[4] The first GHC prototype, bootstrapped in Haskell itself, utilized combinator-based graph reduction techniques to handle lazy evaluation efficiently, with the initial working version ready by early 1990. This culminated in the first beta release on April 1, 1991, which supported core Haskell semantics and marked a milestone in proving lazy functional programming's practicality.[4] Early work was funded primarily through UK public grants, including SERC support for the GRASP project (grants GR/F98444 and GR/F34671) and joint DTI/SERC funding for related functional language research, enabling the academic collaboration at Glasgow.Major Releases and Milestones
The Glasgow Haskell Compiler (GHC) achieved full compliance with the Haskell 98 standard in version 6.0, released on May 28, 2003, marking a significant milestone in stabilizing the language implementation for broader adoption.[16][17] This release focused on refining the core compiler to align precisely with the revised Haskell 98 specification from December 2002, enabling reliable use in production environments. Subsequent versions built on this foundation, with GHC 7.0.1, released on November 16, 2010, introducing support for the Haskell 2010 standard by default, which incorporated extensions like foreign function interface improvements and conditional compilation.[18][19] Later releases emphasized advanced language features, such as GHC 9.0.1 in February 2021, which debuted the LinearTypes extension for resource-sensitive programming, allowing linear types to enforce single-use semantics for values like file handles or continuations.[20][21] GHC 9.4, released in August 2022, added the OverloadedRecordDot extension, enabling more ergonomic record field access via dot notation that supports overloading for custom types.[22][23] As of November 2025, the most recent stable LTS release is GHC 9.10.3, released on September 10, 2025.[24] Key milestones include the introduction of the interactive GHCi environment in GHC 5.00 (April 2001), which revolutionized development by providing an REPL for rapid prototyping and debugging.[25] The LLVM backend arrived around 2009–2010, offering an alternative code generation path that improved performance on certain architectures through LLVM's optimization infrastructure.[26][27] From 2009 to 2014, the Industrial Haskell Group (IHG) provided targeted funding for GHC enhancements, such as dynamic library support on Linux and Windows, addressing industrial needs for deployable binaries.[28][29] In 2018, GHC migrated its source repository to Git and GitLab, streamlining collaboration and issue tracking for the open-source community.[30] GHC adopted a semantic versioning scheme starting with major version 8.0 in 2017, where major releases introduce potentially breaking changes, minor versions add features compatibly, and patch releases focus on fixes, exemplified by the structured progression from 8.0 to subsequent series.[22] This aligns with a consistent release cadence of approximately six months for major versions since the mid-2010s, ensuring timely delivery of innovations while maintaining stability for long-term support (LTS) branches like 9.6 and 9.10. In July 2025, GHC announced a new LTS release policy, with the first LTS branch planned for 9.14 in August 2025.[31][32] In 2024, GHC deprecated support for 32-bit platforms on Darwin (macOS/iOS) and Windows, reflecting declining hardware relevance and developer resource constraints, with binary distributions ceasing and future removal planned.[33] Community governance has evolved with significant involvement from Well-Typed, a consultancy firm that has contributed extensively to GHC development since 2008, including core optimizations and release engineering.[34] The Haskell Prime process, which guides revisions to the Haskell standard, draws heavily from GHC extensions, ensuring that innovations like linear types influence future specifications through committee review. This collaborative model, bolstered by IHG's earlier efforts and ongoing foundation support, underscores GHC's role as the de facto reference implementation.Architecture
Frontend
The frontend of the Glasgow Haskell Compiler (GHC) comprises the initial compilation stages that transform Haskell source code into an intermediate representation suitable for further processing. It handles lexical analysis, parsing, name resolution, type inference and checking, and desugaring, ensuring adherence to Haskell's syntax and semantics while providing robust diagnostics for errors encountered during these phases. This pipeline operates on modules independently where possible, supporting features like Template Haskell splicing that may require iterative passes.[2] Lexical analysis begins with a lexer generated by the Alex tool, which scans the input source file character by character to produce a stream of tokens according to Haskell's lexical conventions, including identifiers, literals, keywords, and symbols. The lexer supports Haskell's layout rule, which uses indentation to imply syntactic structure such as block delimiters, by tracking position information in tokens to enable context-sensitive parsing. This stage filters out comments and whitespace, ensuring the token stream accurately reflects the program's structure without extraneous elements.[2] The parser, implemented using the Happy parser generator from the grammar defined incompiler/GHC/Parser.y, consumes the token stream to construct an abstract syntax tree (AST) in the HsSyn representation, where identifiers are initially raw strings (RdrName). It handles Haskell's context-free grammar, including layout-sensitive constructs like where clauses and list comprehensions, and produces a parse tree that preserves source positions for error reporting. The parser is designed to be modular, allowing reuse in tools like GHCi for interactive input.[2]
The renamer follows parsing and resolves all occurrences of identifiers to unique, qualified names (Name) in the HsSyn AST, managing Haskell's module system by processing import and export declarations to build a global name environment. It handles scoping rules, including lexical scoping, qualified imports, and re-exports, while detecting ambiguities such as name clashes or shadowed bindings and flagging unused imports or local definitions as warnings. Additional tasks include fixing the precedence of infix operators based on their declared fixity and expanding parentheses in expressions to explicit applications. The renamer operates in a single pass per module, producing a renamed AST (HsSyn Name) that serves as input to type checking.[2][35]
Type checking employs Haskell's Hindley-Milner (HM) type system for polymorphic type inference, generating type constraints from the renamed AST and solving them via unification to assign principal types to expressions and declarations. The process creates fresh type variables for unknowns, unifies them during inference (e.g., matching function argument and parameter types), and generalizes polymorphic types at let-bindings using let-generalization rules. For extensions like generalized algebraic data types (GADTs), the type checker integrates specialized unification that allows existential types and pattern-match refinements, ensuring type equality constraints are satisfied without full instantiation. Constraint solving handles type classes and instances through an external solver interface, supporting improvements like the OutsideIn(X) algorithm for better error localization. The output is a type-annotated AST (HsSyn Typechecked), with all types explicit and verified for consistency.[2][36]
Desugaring translates the type-checked Haskell AST into Core, a small, explicitly typed lambda calculus that serves as GHC's intermediate language for optimizations. This stage eliminates surface syntax sugar, such as converting do-notation for monads into bind operations (>>=), list comprehensions into applications of map and filter, and pattern guards into if-then-else constructs with guards. It also expands derived instances (e.g., for Eq or Show) and handles recursive definitions by introducing letrec bindings, resulting in a simplified, functional form without Haskell-specific idioms. The desugared Core retains type annotations and is positioned for the core-to-core optimization pipeline.[2]
Error reporting is integrated across frontend stages to provide actionable diagnostics, with the parser emitting syntax errors tied to token positions, the renamer highlighting scoping issues like undefined names or import conflicts, and the type checker generating detailed type mismatch explanations often including suggested fixes or hole-filled reports. Recent enhancements introduce a structured diagnostic framework using message envelopes for severity (error, warning) and categories, improving clarity and tool integration, such as in IDEs. All messages include source spans for precise location and leverage the AST for context-aware suggestions, minimizing user debugging effort.[2][37]
Core Language and Optimizations
The Core language in GHC is a simplified, explicitly typed functional intermediate representation derived from System F extended with type equality coercions, known as System FC. It features a small set of constructs including variables, literals, applications, lambda abstractions (both term and type), let expressions, and case expressions, enabling a clean foundation for applying optimizations. Desugared Haskell source code is translated into Core by the frontend, providing a uniform platform independent of surface syntax details. This design facilitates modular analysis and transformation, with types tracked explicitly to ensure correctness throughout the pipeline. GHC's optimization pipeline applies over 25 transformation passes to Core code, organized into iterative phases of the central simplifier module. These passes encompass inlining to eliminate function calls, lambda lifting to hoist nested lambdas to top-level bindings, common subexpression elimination to remove redundant computations, and strictness analysis to identify evaluation opportunities. Additional transformations include let-floating for better code layout, beta reduction for simplifying applications, and join-point analysis for optimizing recursive tail calls. The pipeline runs in multiple phases (typically four to two, decreasing iteratively), with each phase applying a sequence of rules to refine the code for efficiency, balancing compile-time cost against runtime performance gains.[38][39] Among the key techniques, the worker/wrapper transformation specializes functions by splitting them into a wrapper that handles boxed arguments and an unboxed worker that performs the core computation, enabling unboxing of primitive types like integers and floats to avoid heap allocation overhead. This is particularly effective for strict functions identified via demand analysis. List fusion, implemented through rewrite rules, optimizes data processing by composing producers and consumers; for example, the foldr/build rule fuses a list-building operation (using the genericbuild combinator) with a right fold (foldr), eliminating intermediate list allocations and reducing constant factors in time and space.[40][41]
Following Core optimizations, the transformed code is converted to the STG (Spineless Tagless G-machine) representation, an abstract graph reduction machine that models Haskell's lazy evaluation semantics without explicit tags on closures, simplifying garbage collection and runtime support. STG introduces low-level details like thunks and update frames while preserving the optimized structure from Core. For profiling and debugging, cost centers—markers for attributing execution costs to specific code regions—can be automatically inserted into Core during or after optimizations, with options like late insertion minimizing interference with passes such as inlining. This allows detailed runtime analysis, such as time and allocation profiling, without unduly compromising generated code quality.[42][43]
As a concrete example, consider fusing sum (a foldr over a list) with a list producer using build:
sum = foldr (+) 0
xs = build (\c n -> ... ) []
Without fusion, this generates an intermediate list xs, allocating heap space. The foldr/build rule rewrites it directly to a loop over the builder's continuation c, avoiding the list entirely and fusing the operations into a single pass. This can yield asymptotic improvements for chained list transformations, as verified in GHC's rule application during simplification.[41][39]
Backend
The backend of the Glasgow Haskell Compiler (GHC) is responsible for transforming the optimized intermediate representation, known as Cmm (a variant of the C-- language), into executable machine code or other target formats. This phase handles low-level code generation, including instruction selection, register allocation, and platform-specific assembly output, ensuring efficient execution on diverse hardware. GHC supports multiple backends to balance compilation speed, code quality, and portability, with the native code generator serving as the default for most scenarios.[44][2] The Native Code Generator (NCG) directly compiles Cmm to assembly code for architectures such as x86, x86-64, ARM, AArch64, PowerPC, and others, producing native executables without external dependencies. It employs instruction selection to map Cmm operations to machine instructions, followed by register allocation using techniques like graph coloring or iterative coalescing to minimize spills and optimize performance. The NCG also applies peephole optimizations, which heuristically rewrite short instruction sequences for efficiency, such as eliminating redundant loads or reordering for better pipeline utilization. This backend excels in compilation speed and supports shared libraries effectively, making it suitable for production builds on supported platforms.[44][45][46] Cmm, derived from the C-- intermediate language, acts as a portable, low-level representation that bridges higher-level optimizations and final code emission, facilitating custom targets through its C-like syntax with explicit stack management and imperative constructs. This design enhances portability by abstracting architecture-specific details until the final generation step, allowing GHC to target new platforms with minimal changes to upstream components. While primarily internal, C-- enables extensions like alternative backends without overhauling the core pipeline.[2][45][47] Starting with version 7.0 in 2010, GHC has offered an optional LLVM backend that translates Cmm to LLVM intermediate representation for further optimization and code generation via the LLVM toolchain, often yielding superior performance in numeric and array-intensive workloads compared to the NCG. This integration requires LLVM versions 13 through 20 installed, including tools likeopt and llc, and is invoked with the -fllvm flag; it supports Linux, macOS, and Windows but incurs higher compilation overhead due to external processing. The backend leverages LLVM's advanced optimizations, such as vectorization, while preserving Haskell's semantics through careful handling of the runtime interface.[44][45][48]
For web development, GHC includes a JavaScript backend, evolved from the independent GHCJS project and merged into the mainline compiler in 2022, which compiles Haskell code to JavaScript while maintaining compatibility with GHC's core pipeline up to optimized STG intermediates. This allows Haskell applications to run in browsers, with ongoing support for features like Template Haskell in related WebAssembly targets.[49][50]
Final linking incorporates the Runtime System (RTS), a C-based component linked into every Haskell executable to manage essential services including a generational copying garbage collector for memory management, lightweight threading via a work-stealing scheduler for parallelism, and I/O operations. The RTS supports concurrent garbage collection options, such as the non-moving collector introduced in GHC 8.10, which reduces latency in threaded programs without requiring code changes beyond the -threaded flag. This setup ensures portability and efficiency across platforms, handling Haskell's non-strict evaluation model transparently.[2][51][52]
Language Implementation
Conformance to Haskell Standards
The Glasgow Haskell Compiler (GHC) aims to conform fully to the Haskell 2010 language standard, serving as its de facto reference implementation for core features, including modules, types, expressions, input/output (I/O), and the foreign function interface (FFI).[53][54] Modules in GHC adhere to the standard's specifications for export and import lists, instance declarations, and separate compilation, enabling modular program structure with abstract datatypes.[55] Type system conformance covers user-defined datatypes, type classes, overloading, and predefined types, ensuring type safety and inference as defined in the report.[56] Expressions follow the standard for variables, operators, lambda abstractions, pattern matching, and constructs like let, case, and do notation.[57] I/O operations conform to the IO monad semantics, including sequencing, exception handling, and file management via handles.[58] The FFI supports interoperability with foreign languages, particularly C, through declarations for external entities and data marshalling.[59] GHC retains partial support for the legacy Haskell 98 standard to maintain compatibility with older codebases, though it is deprecated in favor of Haskell 2010 and later editions.[53] This support includes the core syntax and semantics of Haskell 98 but omits some deprecated features, with GHC defaulting to Haskell 2010 mode unless explicitly configured otherwise.[53] For standard libraries, GHC's base package implements the Haskell 2010 Prelude and core modules, providing conformance for fundamental types, classes, and functions while flagging any GHC-specific additions or modifications through language pragmas. The base package ensures portability of standard I/O, numeric operations, and monadic structures across compliant implementations.[60] Compliance with Haskell standards is verified through GHC's comprehensive testsuite, which includes correctness tests for language features and library behaviors, alongside community-driven validation efforts to align with the official reports.[61] This testing infrastructure helps maintain adherence, though some infelicities persist. Known deviations from Haskell 2010 include variations in lazy evaluation strictness; for instance, GHC's implementation ofseq can eta-expand functions, potentially making certain error-handling cases more defined than specified, which can be adjusted via the -fpedantic-bottoms flag. In I/O, functions like hGetContents may throw exceptions on errors rather than discarding them silently, diverging from Haskell 98 but applicable in Haskell 2010 contexts. Standard library deviations encompass stricter evaluation in functions like splitAt and extended support for numeric literals in Read, such as hexadecimal formats. The FFI lacks support for re-initializing the runtime after hs_exit(), contrary to the addendum's expectations. These deviations are documented to guide users toward standard-compliant code.[53]
GHC also supports extensions beyond Haskell 2010 for advanced features, as covered in separate documentation.[53]
Extensions to Haskell
The Glasgow Haskell Compiler (GHC) extends the Haskell language through a flexible pragmas system that allows users to enable non-standard features on a per-module or global basis. This system supports two primary mechanisms: the LANGUAGE pragma, which can be placed at the top of a Haskell source file to activate specific extensions portably across compilers, and command-line flags prefixed with -X, such as -XOverloadedStrings, for project-wide or invocation-specific enabling.[53][62] Extensions like OverloadedStrings (which treats string literals as instances of the IsString typeclass for polymorphic string handling), BangPatterns (enabling strictness annotations in patterns with !), and RankNTypes (supporting higher-rank polymorphism via explicit forall quantifiers in types) exemplify this system's granularity, allowing developers to opt into enhanced expressiveness without altering core Haskell compliance.[63] GHC's extensions include several influential innovations in metaprogramming, type systems, and concurrency. Template Haskell, introduced in 2003, enables compile-time metaprogramming by allowing Haskell code to generate and splice other Haskell code during compilation, facilitating tasks like automated boilerplate derivation and domain-specific languages.[64] Generalized algebraic data types (GADTs), added in 2005, extend algebraic data types to support existential quantification and refined return types for constructors, enabling more precise type-safe representations such as typed expression evaluators.[65] Type families, available since 2007, introduce type-level functions that compute types from other types, supporting associated type families in classes for modular type computations like vector indexing or heterogeneous lists.[66] More recent extensions address advanced resource management and syntax ergonomics. Linear types, implemented in GHC 9.0 in 2021, introduce multiplicity tracking where linear arrows 1 -> require their argument to be used exactly once, enforced through static linearity checks during type inference and desugaring to ensure no accidental duplication or discarding of resources like file handles or GPU buffers.[67][68] Record dot syntax, stabilized in GHC 9.2 and enhanced in subsequent releases around 2023 via the OverloadedRecordDot extension, provides concise field access (e.g., person.name) by desugaring to getField calls, improving readability for large records while supporting overloaded projections.[69][70] GHC integrates Software Transactional Memory (STM) as a core concurrency primitive since version 6.4, providing atomic, composable transactions via the STM monad and combinators like atomically, retry, and orElse, which abstract shared state updates with automatic rollback on conflicts.[71][72] For parallelism, the -threaded flag activates runtime support for multicore execution, paired with strategies from the parallel package using par (to spark parallel evaluation) and combinators in the Eval monad, or the Par monad from monad-par for structured deterministic parallelism in computations like divide-and-conquer algorithms.[73][74] Extensions can be disabled individually with -fno-extension or via the NoExtension pragma, and recent GHC versions (9.0+) introduce language editions like GHC2021 and GHC2024, which bundle sensible defaults such as BangPatterns and TypeApplications for new projects, reducing boilerplate while maintaining opt-in control through flags or pragmas.[53][75] This ecosystem of extensions, managed via GhcFlags in build tools like Cabal, empowers Haskell programmers to balance expressiveness, safety, and performance beyond the Haskell 2010 standard.[76]Portability
Supported Platforms
The Glasgow Haskell Compiler (GHC) runs natively on a range of operating systems and architectures, categorized into support tiers that reflect the level of testing, maintenance, and official binary availability. Tier 1 platforms are fully tested via continuous integration and must function correctly for each release, ensuring reliable host environments for compiling Haskell code. These include x86-64 architectures on Linux (across major distributions such as Ubuntu 22.04+, Debian 12, Fedora 40+, Alpine 3.20+), macOS (version 12.0+ including Sonoma 14 and Sequoia 15), and 64-bit Windows (10/11).[77][78]| Tier | Platforms | Notes |
|---|---|---|
| 1 | x86-64 Linux, x86-64 macOS, x86-64 Windows, x86-64/AArch64 FreeBSD 13.x | Full CI testing; official binaries provided; primary focus for releases (as of GHC 9.12, 2025).[77][79] |
| 2 | AArch64 Linux, x86-64 FreeBSD 12.x, x86-64 OpenBSD, x86 Linux | Partial testing; functional with community maintenance; binaries available for some (e.g., AArch64 Linux on Debian 12, Alpine 3.20+); FreeBSD binaries as Tier 2 in GHC 9.14 (2025). 32-bit x86 Linux remains supported but deprecated in favor of 64-bit.[77][80] |
Cross-Compilation Capabilities
The Glasgow Haskell Compiler (GHC) enables cross-compilation, allowing Haskell code developed on a host system to be compiled for diverse target architectures and environments without requiring a native compiler on the target. This capability is essential for deploying Haskell applications to embedded systems, mobile devices, and web platforms, leveraging GHC's modular backend and toolchain configuration. Cross-compilation in GHC involves building a specialized version of the compiler configured for the desired target, which then generates executables or libraries compatible with that architecture.[83] GHC supports cross-compilation to several key architectures, including x86-64, AArch64 (ARM64), PowerPC, s390x, Tier 3 support for RISC-V (64-bit) since GHC 9.12 (2025), as well as WebAssembly via its native backend (introduced in GHC 9.6, with Template Haskell and GHCi support added in 9.10+ as of 2024–2025). For non-native targets, users must first build a cross-compiler using the./configure --target=<triple> script, where <triple> specifies the target (e.g., aarch64-unknown-linux-gnu for ARM64 Linux), followed by make to compile GHC itself for that target. This process requires a cross-toolchain, such as GCC or Clang configured for the target, to handle C dependencies and foreign function interfaces (FFI). Once built, the cross-compiler (often named like aarch64-linux-gnu-ghc) can be invoked directly or integrated with build tools like Cabal, using commands such as cabal configure --with-compiler=aarch64-linux-gnu-ghc to compile projects for the target, enabling workflows for platforms like Android and iOS through specialized setups that link against mobile SDKs. Recent improvements, such as the ghc-toolchain tool, simplify this by automating toolchain detection and configuration for common targets.[22][84][83][85][86]
Cross-compilation presents challenges, particularly in handling architecture-specific components like the runtime system (RTS), which must be ported or rebuilt for the target to manage memory and threading correctly, often requiring manual adjustments for new architectures. Foreign calls via FFI necessitate a matching cross-C compiler to link libraries, while endianness differences are addressed through target-specific code generation in GHC's backend. To support Template Haskell during cross-compilation, an external interpreter (iserv) must be built and deployed for the target, as the host compiler cannot execute target-specific splices directly. Solutions include using remote iserv proxies for mobile targets, allowing the host to orchestrate compilation while running target code in emulators.[83][87][88]
Practical examples demonstrate GHC's cross-compilation in action: for embedded systems like Raspberry Pi (AArch64), developers build a cross-GHC on x86 hosts and compile Haskell programs using standard Cabal workflows, linking against ARM toolchains for deployment. Mobile development, such as Haskell for Android, involves configuring GHC with Android NDK cross-compilers to produce shared libraries integrated into Java/Kotlin apps via JNI. For web environments, integration with GHCJS allows compilation to JavaScript, though the native WebAssembly backend in GHC provides a more direct path for browser-targeted executables, albeit experimentally as of 2025, with growing ecosystem integration including GHCi browser mode. Limitations include incomplete cross-compilation support for Windows targets from Unix-like hosts without Cygwin or MSYS2 environments, and ongoing experimental status for WebAssembly.[89][90]
Tools and Ecosystem
Interactive Environment (GHCi)
GHCi serves as the interactive read-eval-print loop (REPL) environment for the Glasgow Haskell Compiler (GHC), launched via theghci command-line tool. It functions primarily as a bytecode interpreter, allowing developers to load Haskell modules, evaluate expressions interactively, and interpret programs on the fly while supporting most GHC language extensions. Introduced with GHC version 6.0 in May 2003, GHCi has become essential for exploratory coding, rapid prototyping, and debugging in Haskell development.[91][92]
Key features of GHCi include direct expression evaluation at the prompt, where inputs like 1 + 2 immediately return 3, and support for IO actions such as putStrLn "hello". Type inspection is facilitated by the :type command, which infers and displays types—for instance, :type [length](/page/Length) yields [a] -> Int (or more generally, Foldable t => t a -> Int with extensions). The integrated debugger enables setting breakpoints via :break (e.g., :break 2 for line 2 of a module), single-stepping through reductions with :step, and variable inspection during pauses using :print or :force. Multi-shot evaluation allows handling nested contexts, with tools like :trace for step traces and :hist for evaluation history, enhancing traceability in complex sessions.[93][94]
GHCi compiles loaded modules to bytecode by default, a format optimized for quick interpretation and reloading during development, which contrasts with slower source-level evaluation. For performance gains—typically 10 to 20 times faster than bytecode—it can link pre-compiled object code using the -fobject-code or -dynamic flags, though this mode disables interactive debugging features like breakpoints and stepping.[95][96]
Customization options make GHCi adaptable to user workflows, including .ghci configuration files in the home directory or project root for loading modules or setting preferences on startup. Command history is managed with a configurable depth (default 50 via -fghci-hist-size), and editor integration is supported through :edit to open files at errors or via :set editor for custom tools. Prompt customization, such as :set prompt "%s> " (where %s inserts the current module), aids visibility in integrated development environments.[97][98]
Advanced capabilities include the statement monad for imperative-style interactions at the prompt, enabling do-notation sequences like x <- getLine; return (length x) that default to the IO monad. Profiling within the REPL is possible using the external interpreter mode (-fexternal-interpreter -prof), which generates stack traces and statistics for interpreted code, requiring profiled dependencies.[99][100]