Arnaud Spiwack, Csongor Kiss,
Jean-Philippe Bernardy, Nicolas Wu,
Richard A. Eisenberg
Generic Inference for Capabilities and Uniqueness
Design sketch
2017
2018
POPL paper
Merged in GHC
2020
2021
GHC 9.0.1 released
Today
2022
A -> B
A %1 -> B
(plus polymorphism stuff, but not for today)
If the result is consumed exactly once, the argument is consumed exactly once
swap :: Int -> Int -> MArray a %1 -> MArray A
swap i j as =
let
!(as', Ur ai) = get i as
!(as'', Ur aj) = get j as'
as''' = set i aj as''
as'''' = set j ai as'''
in
as''''
val swap : [a] duplicable a
=> (i: int, j: int, as: marray a) -> () =
let ai = get (as, i) in
let aj = get (as, j) in
set (as, i, aj);
set (as, j, ai)
nub :: Eq a => [a] -> [a]
Constraints
set :: RW n %1 => Int -> a -> MArra…
swap :: RW n %1 => Int -> Int -> MArray n a -> () ⧀ RW n
swap i j as =
let
!Ur ai = get i as
!Ur aj = get j as
!() = set i aj as
!() = set j ai as
in
()
newMArray :: Int -> (MArray a %1 -> Ur b) %1 -> Ur b
fromList :: [a] -> Array a
fromList as =
unUr $ newMArray (length as) $ \arr ->
let arr' = foldr (uncurry set) (zip [1..] as) arr in
freeze arr'
newMArray :: Linearly %1 => Int -> MArray a
fromList :: Linearly %1 => [a] -> Array a
fromList as =
let arr = newArray (length as) in
let arr' = foldr (uncurry set) (zip [1..] as) arr in
unUr $ freeze arr'
+
Declarative system
Constraint generation
Constraint solving
Inferred as
soundness
https://slides.com/aspiwack/icfp2022
https://www.tweag.io/blog/tags/linear-types/
https://dl.acm.org/doi/10.1145/3547626