Implementing Linear Haskell
Matthew Pickering & Arnaud Spiwack
Linear Haskell: a Summary
Linearity on the arrow
type of linear functions
can be any type
\( f \) linear
\(\iff\)
\(f u\) consumed once \(\Rightarrow\) \(u\) consumed once
Linearity, not uniqueness
Backwards compatible
Multiplicity polymorphism
\( a \rightarrow b = a \rightarrow_\omega b\)
\( a \multimap b = a \rightarrow_1 b\)
\( a \rightarrow_p b \): polymorphic
Instances
Properties
Semiring (
e.g. \(a*(b+c) = a*b + a*c\))
Ordered (
e.g. \(a\leqslant c \Rightarrow a+b\leqslant c+b\))
Joins ( i.e. \(a\vee b\leqslant c \iff a\leqslant c \wedge b\leqslant c\))
\(\pi \leqslant \omega \)
Typing rules
A type-checking algorithm
Multiplicity data type
data Mult
= Zero
| One
| Omega
| Mult `MultAdd` Mult
| Mult `MultMul` Mult
| MultTy Type
data Weighted a
= Weighted Mult a
Weighted Type
Type
often
variables are mere type variables
data Multiplicity
= Omega
| One
Multiplicities as a type
FunTy
FunTyCon :: Type
FunTy :: Mult -> Type -> Type -> Type
Arguments:
RuntimeRep*2, Mult, Type*2
Propagating to Core
data Var
= …
| Id {…
varType :: Type,
varMult :: Mult }
This is new
data Coercion
= …
| FunCo Role Coercion Coercion Coercion
New: multiplicity coercion
Core transformations
The Float Out incident
(and inlining, and CSE,…)
Alias-like binders
Pushing coercions
What happened to \(co_{mult}\)‽ Bad! bad! bad!
Only push coercion when \(co_{mult} = \mathsf{refl}\).
data Coercion
= …
| FunCo Role Coercion Coercion Coercion
Wrapper for all
This is key!
When used as a term.
Crucial for backwards compatibility
"inferred": doesn't affect visible type applications
Implemented as a wrapper
Strictness analysis: CPR
$wf :: A -> (# C, D #)
f :: A -> B
f x = case $wf x of
(# y, z #) -> B y z
Linear: \(\verb|$wf x|\) is consumed exactly once.
But what if \(\mathsf{B} : a \multimap b \rightarrow B\) ?
Then we need \(\verb|(#,#)| : a \multimap b \rightarrow \verb|(#|a,b\verb|#)|\)
Later! For now, deactivate CPR when not all fields linear
https://github.com/tweag/ghc/tree/linear-types
https://ghc.haskell.org/trac/ghc/wiki/LinearTypes/Implementation
https://github.com/ghc-proposals/ghc-proposals/pull/111
Implementing Linear Haskell
By Arnaud Spiwack
Implementing Linear Haskell
As the linear type proposal is underway, and the specifics of how linear types should be exposed in Haskell are being debated, you may wonder: but how is it implemented? Is it easy? Is it hard? Is it small? Is it big? As a GHC developer what would it change for me in practice? This talk will describe our implementation in progress of the linear type feature. How we changed the linear arrow constructor, how type checking is performed, what changes are necessary in Core to account for linearity, etc…
- 1,986