Welcome to Hasktorch!
Hasktorch is a Haskell library for scientific computing and differentiable programming. It is built on libtorch — the same C++ core that powers PyTorch — so it executes on the same kernels, the same automatic differentiation tape, and the same GPUs, while the surface you program against is Haskell: pure functional programming, an expressive type system, and compile-time checking of the things deep-learning code most often gets wrong at runtime.
The library is layered, and this tutorial follows the layers. Each one is optional: you can be productive with the untyped API alone, and every further part buys more static guarantees for more type-level machinery.
Part I — The untyped API
The dynamically-shaped layer, closest to PyTorch: if you have used
torch, this is the same mental model with Haskell syntax. Shapes
live in values, mistakes surface at runtime.
- Getting Started — installation and first steps
- Tensors — creation, values, shapes, devices
- Randomness — random tensors and effects
- Automatic Differentiation — independent tensors and gradients
- Differentiable Programs — models as records of parameters
- Linear Regression — a first complete training loop
Part II — The typed API
Shapes, dtypes, and devices move into the types, so a mismatched matrix multiplication or a misplaced batch dimension is a compile error. The guarantee compounds: if the program compiles, the forward pass, loss, gradients, and optimizer steps all agree.
- Typed Tensors — shape-indexed tensors and typed autograd
- Named Tensors and Lenses — dimensions with meaning: records as axes, fields as lenses
- Indexing and Slicing — PyTorch's
[1, :, 1:3:2]in both APIs, bounds-checked in the typed one - Lenses — slicing lenses and whole-model traversals (e.g. convert a model to
Halfin one line), in both APIs
Part III — Semantics: writing the math, running the tensors
The layer this tutorial builds towards: element-level formulas and architectural structure expressed directly, with the tensor execution derived from them.
- Graded and Staged Tensor Programs — why
Tensoris not aMonadand what it is instead; element formulas that run both as their own specification and as vectorized ATen calls - Moving Dimensions —
dimUp/dimDown: dimensions migrate between tensor axes and Haskell structure, up to tree-shaped data - Attention, Equation by Equation — a trainable decoder block in sixty lines, one definition per equation
- Networks as Arrows — models compose with
>>>,&&&, andprocnotation; ResNet skips and layer stacks as folds
Part IV — The runtime underneath
- TorchScript and the JIT — tracing models from Haskell, and measured reality about fusion
Part V — Training in practice
The engineering around the math: getting data in, updating parameters efficiently, and getting trained models out.
- Data Pipelines — streaming datasets in constant memory: CSV rows as records, shuffling, prefetch
- Optimizers — purely functional optimizers whose state is a value, and libtorch's in-place ones; when each wins
- Saving and Loading — checkpoints, and pickle interop with PyTorch in both directions
Chapters 1–6 assume no Haskell type-level programming at all. Chapters 7–10 use type-level naturals and records. Chapters 11–15 are where the research-flavoured ideas live, and 16–18 need only Part I again — every chapter is grounded in code that is compiled, executed, and tested in CI, with the rendered output on these very pages.
Looking for a reference? See the API docs hosted on hasktorch.org.