Matthew Pickering & Arnaud Spiwack
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
\( 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 \)
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
FunTyCon :: Type
FunTy :: Mult -> Type -> Type -> Type
Arguments:
RuntimeRep*2, Mult, Type*2
data Var
= …
| Id {…
varType :: Type,
varMult :: Mult }
This is new
data Coercion
= …
| FunCo Role Coercion Coercion Coercion
New: multiplicity coercion
(and inlining, and CSE,…)
What happened to \(co_{mult}\)‽ Bad! bad! bad!
Only push coercion when \(co_{mult} = \mathsf{refl}\).
data Coercion
= …
| FunCo Role Coercion Coercion Coercion
This is key!
When used as a term.
Crucial for backwards compatibility
"inferred": doesn't affect visible type applications
Implemented as a wrapper
$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