Haskell's web ecosystem, ported to Lean 4 with maximalist typing.
257 compile-time theorems · 45 ported libraries · 241 Lean modules
Warning
This repository is archived in favor of linen. linen sticks less closely to Haskell's API surface, is more idiomatic to Lean, and provides many more proofs (no partial, no sorry, etc.). New work should happen there.
hale ports 45 Haskell libraries (241 Lean modules) covering everything from foundational types to a full HTTP/1-2-3 web server stack. Unlike a minimal port, types encode correctness proofs, invariants, and guarantees wherever feasible:
- Correctness: Lawful typeclasses (
LawfulBifunctor,LawfulCategory,LawfulTraversable) with verified laws - Invariants:
Ratioenforces positive denominator and coprimality in its type;NonEmptyguaranteeslength >= 1 - Proofs:
clampreturns{y : a // lo <= y && y <= hi};Fixed.add_exactproves addition preserves precision - 257 compile-time verified theorems across 52 files, checked by the Lean 4 kernel
Add to your lakefile.toml:
[[require]]
name = "hale"
git = "<repository-url>"
rev = "main"Then import:
import Hale
open Hale| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.Base |
base | Foundational types, functors, monads, concurrency |
Hale.ByteString |
bytestring | Byte array operations (strict, lazy, builder) |
Hale.Word8 |
word8 | Word8 character classification |
Hale.Time |
time | Clock and time types |
Hale.STM |
stm | Software transactional memory |
Hale.DataDefault |
data-default | Default values |
Hale.ResourceT |
resourcet | Resource management monad |
Hale.UnliftIO |
unliftio-core | MonadUnliftIO |
Hale.Conduit |
conduit | Composable streaming data pipelines |
| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.Network |
network | POSIX sockets with phantom state |
Hale.IpRoute |
iproute | IP address types |
Hale.Recv |
recv | Socket receive |
Hale.StreamingCommons |
streaming-commons | Streaming network utilities |
Hale.SimpleSendfile |
simple-sendfile | sendfile(2) wrapper |
Hale.TLS |
tls | TLS via OpenSSL FFI |
| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.HttpTypes |
http-types | HTTP methods, status, headers, URI |
Hale.HttpDate |
http-date | HTTP date parsing |
Hale.Http2 |
http2 | HTTP/2 framing, HPACK, server |
Hale.Http3 |
http3 | HTTP/3 framing, QPACK |
Hale.QUIC |
quic | QUIC transport |
Hale.BsbHttpChunked |
bsb-http-chunked | Chunked transfer encoding |
Hale.HttpClient |
http-client | HTTP client with pluggable transport |
Hale.HttpConduit |
http-conduit | HTTP + Conduit integration |
Hale.Req |
req | Type-safe HTTP client |
| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.WAI |
wai | Request/Response/Application/Middleware |
Hale.Warp |
warp | HTTP/1.x server |
Hale.WarpTLS |
warp-tls | HTTPS via OpenSSL |
Hale.WarpQUIC |
warp-quic | HTTP/3 over QUIC |
Hale.WaiExtra |
wai-extra | 36 middleware modules |
Hale.WaiAppStatic |
wai-app-static | Static file serving |
Hale.WaiHttp2Extra |
wai-http2-extra | HTTP/2 server push |
Hale.WaiWebSockets |
wai-websockets | WebSocket WAI handler |
Hale.WebSockets |
websockets | RFC 6455 WebSocket protocol |
| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.CaseInsensitive |
case-insensitive | Case-insensitive strings |
Hale.Vault |
vault | Type-safe heterogeneous storage |
Hale.AutoUpdate |
auto-update | Periodic cached values |
Hale.TimeManager |
time-manager | Connection timeout management |
Hale.Cookie |
cookie | HTTP cookie parsing |
Hale.MimeTypes |
mime-types | MIME type lookup |
Hale.Base64 |
base64-bytestring | RFC 4648 codec |
Hale.FastLogger |
fast-logger | Buffered thread-safe logging |
Hale.WaiLogger |
wai-logger | WAI request logging |
Hale.UnixCompat |
unix-compat | POSIX compatibility |
Hale.AnsiTerminal |
ansi-terminal | Terminal ANSI codes |
Hale.PSQueues |
psqueues | Priority search queues |
| Lean Package | Haskell Package | Description |
|---|---|---|
Hale.DataFrame |
dataframe (adapted) | Tabular data with typed columns, CSV I/O |
Lean 4 is a dependently-typed proof assistant that compiles to efficient native code. Hale leverages this to turn protocol specs, resource lifecycles, and algebraic laws into compile-time obligations -- verified by the kernel, then erased at runtime (zero overhead).
- Phantom state machines:
Socket (state : SocketState)makes it a type error tosendon an unconnected socket orclosean already-closed one (proof obligation:state != .closed, discharged bydecide) - Indexed monads:
AppM .pending .sent ResponseReceivedenforces that a WAI application callsrespondexactly once -- double-respond is a compile-time error, not a runtime crash - Proof-carrying structures:
Ratiocarriesden_posandcoprimeproofs;Settingscarriestimeout_pos-- all erased at runtime (zero cost) - Algebraic laws: 257 theorems (
bimap_id,bind_assoc,map_id,connAction_http11_default, ...) verified by the Lean kernel
- docs/ -- Per-module documentation with API mappings and examples
- docs/Proofs.md -- Complete catalog of all 257 theorems
- Tests/ -- 82 Lean test files
- Tests/cross-check/ -- 9 Haskell cross-verification scripts
nix-shell # Nix users: enter shell with OpenSSL + pkg-config
lake build # Build the library
lake exe hale # Run smoke tests
lake build hale-tests && lake exe hale-tests # Run test suite
bash tests/cross-check/run-all.sh # Cross-check with Haskell (requires GHC)Requires OpenSSL headers for TLS support. On non-Nix systems, ensure pkg-config openssl works (e.g., brew install openssl pkg-config on macOS, apt install libssl-dev pkg-config on Debian/Ubuntu).
See LICENSE for details.