lazyppl
Lazy Probabilistic Programming Library
https://lazyppl-team.github.io/
| LTS Haskell 23.28: | 1.0 |
| Stackage Nightly 2026-11-03: | 1.1.0 |
| Latest on Hackage: | 1.1.0 |
lazyppl-1.1.0@sha256:f72644c2b0f88ef71ca55bdd93e85bab20753197131681d1939fbe1af328b4f4,6486Module documentation for 1.1.0
LazyPPL
LazyPPL is a Haskell library for Bayesian probabilistic programming, drawing on the fact that lazy data structures are a natural idiom for programming with infinite-dimensional Bayesian methods such as Poisson/Gaussian/Dirichlet processes.
The crucial semantic idea, inspired by developments in synthetic probability theory, is to work with two separate monads: an affine monad of probability, which supports laziness, and a commutative, non-affine monad of measures, which does not. This gives a Metropolis-Hastings implementation that works with lazy programs.
The main LazyPPL modules are on Hackage and Stackage. Various worked examples in literate Haskell are at https://lazyppl-team.github.io.
Laziness lets us specify non-parametric models cleanly: processes or infinite-dimensional functions only have their finite explored portion materialised. We have first-class
- stochastic memoization:
memoize :: (a -> Prob b) -> Prob (a -> b) - Gaussian processes:
wiener :: Prob (Double -> Double) - point processes:
poissonPP :: Double -> Double -> Prob [Double](in the example demos) - Dirichlet processes:
dp :: Double -> Prob a -> Prob (Prob a)
Examples
WienerDemo(lhs) is a simple implementation of regression using a Wiener process. Via maintaining a hidden table of previous calls, it appears to be a bona fide random function $R\to R$ constructed lazily. Some values are sampled during simulation, others during plotting.
RegressionDemo(lhs) demonstrates piecewise linear regression. The change points are drawn from a lazy Poisson process.
Clustering(lhs) contains some simple clustering examples, where the number of clusters is unknown. Stick-breaking is lazy, and we use stochastic memoization.
ProgramInduction(lhs) is a simple example of program induction over an arithmetic language. Random expressions are represented as an infinite forest with a finite path through it.
- Feature extraction via the Indian Buffet Process, and relation inference via the Mondrian Process and a Chinese-Restaurant-Process-based Infinite Relational Model.
Library
LazyPPL.hsprovides the core monads and inference.Probis an affine monad of probability measures.Measis a non-affine monad of unnormalised measures withsampleandscore. The Metropolis-Hastings algorithmmhtakes a probabilitypof changing any given site of the rose tree of random seeds. Settingp=1/num_sitesapproximates single-site MH andp=1recovers multi-site MH. We can’t compute the number of active sites without forcing more of the lazy tree, so we use thisp-parameterised form. A second algorithm,mh1inlazyppl-singlesite, implements a single-site proposal kernel by inspecting the Haskell heap.LazyPPL/Distributions.hsandLazyPPL/Distributions/*provide common distributions and abstract types capturing exchangeability. For example,newCustomer :: Restaurant -> Prob Tablefor the Chinese Restaurant Process (DirichletP.hs) andRestaurant -> Prob [Dish]for the Indian Buffet Process (IBP.hs).
Installation
Build with Cabal: install GHCup for GHC 9.14.1 and Cabal 3.18.2.0, then cabal update and cabal build in the repo root. First build takes a few minutes.
Run a demo: cabal run -fdemos wiener-exe (or regression-exe, clustering-exe, etc.), or explore in the REPL with cabal repl lib:lazyppl.
The library is pure Haskell and needs no LAPACK or BLAS installation. The plotting demos use the matplotlib Haskell wrapper, which calls into Python: sudo apt-get install -y --no-install-recommends python3-matplotlib python3-numpy python3-scipy python-is-python3.
To try lazyppl in your browser without installing anything, click . This opens a ready-to-use VS Code environment with GHC and Cabal already in place.
Writing your own probabilistic models
Under executables: in examples/package.yaml, add a stanza and run hpack examples (0.39.6) to regenerate examples/lazyppl-examples.cabal:
executables:
# ...
mymodel-exe:
main: MyModel.hs
source-dirs: models
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
- -main-is MyModel
dependencies:
- lazyppl
Run with cabal run mymodel-exe, or open in the REPL: cabal repl exe:mymodel-exe.
Changes
Changelog for lazyppl
1.1.0
Added
lazyppl-examples: separate examples and plotting package- Playground: interactive browser models
- Example pages: locally served fonts and icons
Changed
- Build: Cabal and GHC 9.6.7, 9.12.4, 9.14.1
gp,wiener: pure Haskell without LAPACKmh,mhirreducible: lower stream memory retentionmemrec:Ordkeys withoutShow- Integer
memoize: restricted toProb - Distributions: validate inputs and parameter domains
beta,dirichlet: reject unsupported shape parameters- Random labels and acceptance draws: open interval (0,1)
mh,mhirreducible,weightedsamples,wis: separate generator per runsuperuniformbounded: bounded graph angle sampling
Fixed
wis: resample from all weighted samples- Integer
memoize: return values at their own indices mh,mhirreducible,wis: zero and invalid weightsmh1: reject proposals without reverse sitesbeta,dirichlet: sampling at numerical boundariesbeta,dirichlet: reject unsupported custom tree labelscategorical: rounding with finite and infinite streamscategorical: accept finite probabilities with a rounding-sized shortfall- Dirichlet processes: small-stick accumulation
poisson: sampling at extreme labelsibp: first customer’s dish countgp: initial and conditional distributionswiener: variance at extreme timesnormalLogPdf,betaLogPdf,dirichletLogPdf: extreme-input accuracybinomialLogPmf: large-count accuracygammaLogPdf,poissonLogPmf: extreme-input accuracy- Memoization, Gaussian processes and counters: concurrent state
uniformbounded,uniformBoundedLogPdf: overflowing bound differences- Playground: retry failed WebAssembly downloads
- Playground: validate results before plotting
- Mondrian playground: reject overlaps and duplicate identifiers
- GraphDemo: graph probabilities and figure edges
- Example pages: correct maximum-likelihood sample labels
- Example pages: syntax colours in dark mode
- Website generation: preserve prior site on build failure
Removed
LazyPPL.SingleSite: moved tolazyppl-singlesitelazyppl:hmatrix, LAPACK and plotting dependencies
1.0.1
- Add support for GHC 9.8 and 9.10
- Drop upper bounds on dependencies (except
base) - Add log-density / log-PMF functions:
normalLogPdf,gammaLogPdf, etc. - Export
scoreLogandscoreProductLog(already defined in 1.0, now visible) - Remove
monad-extrasdependency
1.0
- Initial Hackage release