Skip to content

Commit 3e17b9e

Browse files
edwinbandrevidela
authored andcommitted
Remove linearity subtyping
It's disappointing to have to do this, but I think necessary because various issue reports have shown it to be unsound (at least as far as inference goes) and, at the very least, confusing. This patch brings us back to the basic rules of QTT. On the one hand, this makes the 1 multiplicity less useful, because it means we can't flag arguments as being used exactly once which would be useful for optimisation purposes as well as precision in the type. On the other hand, it removes some complexity (and a hack) from unification, and has the advantage of being correct! Also, I still consider the 1 multiplicity an experiment. We can still do interesting things like protocol state tracking, which is my primary motivation at least. Ideally, if the 1 multiplicity is going to be more generall useful, we'll need some kind of way of doing multiplicity polymorphism in the future. I don't think subtyping is the way (I've pretty much always come to regret adding some form of subtyping). Fixes idris-lang#73 (and maybe some others).
1 parent ef0c5fa commit 3e17b9e

File tree

44 files changed

+191
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+191
-204
lines changed

CHANGELOG.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Command-line options changes:
1515
provided. An explicit `0` has the effect of simulating a terminal with
1616
unbounded width.
1717

18-
Compiler changes:
18+
Language and compiler changes:
1919

2020
* Added new syntax for named applications and the bind-all-explicits pattern:
2121

@@ -31,6 +31,14 @@ Compiler changes:
3131
boundaries to the AST nodes `FC`.
3232
* New experimental ``refc`` code generator, which generates C with reference
3333
counting.
34+
* `%hint` annotations one local definitions (in `let` or `where` blocks) now
35+
work, meaning that local definitions can be searched in auto implicit search.
36+
* Local implementations of interfaces now work.
37+
* Removed multiplicity subtyping, as this appears to be unsound and causes more
38+
problems than it solves. Unfortunately, this means you sometimes now need to
39+
write linear versions of functions as special cases. (Though note that the 1
40+
multiplicity is still considered experimental, so hopefully this will change
41+
for the better in the future!)
3442

3543
REPL/IDE mode changes:
3644

libs/base/Control/App.idr

+3-3
Original file line numberDiff line numberDiff line change
@@ -213,21 +213,21 @@ get tag @{MkState r}
213213
MkAppRes (Right val)
214214

215215
export
216-
put : (0 tag : _) -> State tag t e => (1 val : t) -> App {l} e ()
216+
put : (0 tag : _) -> State tag t e => (val : t) -> App {l} e ()
217217
put tag @{MkState r} val
218218
= MkApp $
219219
prim_app_bind (toPrimApp $ writeIORef r val) $ \val =>
220220
MkAppRes (Right ())
221221

222222
export
223-
modify : (0 tag : _) -> State tag t e => (1 p : t -> t) -> App {l} e ()
223+
modify : (0 tag : _) -> State tag t e => (p : t -> t) -> App {l} e ()
224224
modify tag f
225225
= let (>>=) = bindL in
226226
do x <- get tag
227227
put tag (f x)
228228

229229
export
230-
new : t -> (1 p : State tag t e => App {l} e a) -> App {l} e a
230+
new : t -> (p : State tag t e => App {l} e a) -> App {l} e a
231231
new val prog
232232
= MkApp $
233233
prim_app_bind (toPrimApp $ newIORef val) $ \ref =>

libs/base/Control/Monad/Either.idr

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import Control.Monad.State
1919

2020
public export
2121
data EitherT : (e : Type) -> (m : Type -> Type) -> (a : Type) -> Type where
22-
MkEitherT : (1 _ : m (Either e a)) -> EitherT e m a
22+
MkEitherT : m (Either e a) -> EitherT e m a
2323

2424
export
2525
%inline

libs/base/Control/Monad/ST.idr

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mutual
2323

2424
export
2525
Applicative (ST s) where
26-
pure = MkST . pure
26+
pure x = MkST (pure x)
2727
(<*>) f a = pure $ !f !a
2828

2929
export

libs/base/Data/IORef.idr

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ readIORef (MkRef m) = primIO (prim__readIORef m)
2525

2626
%inline
2727
export
28-
writeIORef : HasIO io => IORef a -> (1 val : a) -> io ()
28+
writeIORef : HasIO io => IORef a -> (val : a) -> io ()
2929
writeIORef (MkRef m) val = primIO (prim__writeIORef m val)
3030

3131
export

libs/base/Data/List1.idr

+10-10
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@ record List1 a where
1515

1616
||| Forget that a list is non-empty
1717
public export
18-
forget : (1 xs : List1 a) -> List a
18+
forget : (xs : List1 a) -> List a
1919
forget (x ::: xs) = x :: xs
2020

2121
||| Check whether a list is non-empty
2222
export
23-
fromList : (1 xs : List a) -> Maybe (List1 a)
23+
fromList : (xs : List a) -> Maybe (List1 a)
2424
fromList [] = Nothing
2525
fromList (x :: xs) = Just (x ::: xs)
2626

2727
------------------------------------------------------------------------
2828
-- Basic functions
2929

3030
public export
31-
singleton : (1 x : a) -> List1 a
31+
singleton : (x : a) -> List1 a
3232
singleton a = a ::: []
3333

3434
export
@@ -59,39 +59,39 @@ foldl1 n c (x ::: xs) = foldl c (n x) xs
5959
-- Append
6060

6161
export
62-
appendl : (1 xs : List1 a) -> (1 ys : List a) -> List1 a
62+
appendl : (xs : List1 a) -> (ys : List a) -> List1 a
6363
appendl (x ::: xs) ys = x ::: xs ++ ys
6464

6565
export
66-
append : (1 xs, ys : List1 a) -> List1 a
66+
append : (xs, ys : List1 a) -> List1 a
6767
append xs ys = appendl xs (forget ys)
6868

6969
export
70-
lappend : (1 xs : List a) -> (1 ys : List1 a) -> List1 a
70+
lappend : (xs : List a) -> (ys : List1 a) -> List1 a
7171
lappend [] ys = ys
7272
lappend (x :: xs) ys = append (x ::: xs) ys
7373

7474
------------------------------------------------------------------------
7575
-- Cons/Snoc
7676

7777
public export
78-
cons : (1 x : a) -> (1 xs : List1 a) -> List1 a
78+
cons : (x : a) -> (xs : List1 a) -> List1 a
7979
cons x xs = x ::: forget xs
8080

8181
export
82-
snoc : (1 xs : List1 a) -> (1 x : a) -> List1 a
82+
snoc : (xs : List1 a) -> (x : a) -> List1 a
8383
snoc xs x = append xs (singleton x)
8484

8585
------------------------------------------------------------------------
8686
-- Reverse
8787

8888
public export
89-
reverseOnto : (1 acc : List1 a) -> (1 xs : List a) -> List1 a
89+
reverseOnto : (acc : List1 a) -> (xs : List a) -> List1 a
9090
reverseOnto acc [] = acc
9191
reverseOnto acc (x :: xs) = reverseOnto (x ::: forget acc) xs
9292

9393
public export
94-
reverse : (1 xs : List1 a) -> List1 a
94+
reverse : (xs : List1 a) -> List1 a
9595
reverse (x ::: xs) = reverseOnto (singleton x) xs
9696

9797
------------------------------------------------------------------------

libs/base/Data/Vect.idr

+16-19
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ data Vect : (len : Nat) -> (elem : Type) -> Type where
1414
Nil : Vect Z elem
1515
||| A non-empty vector of length `S len`, consisting of a head element and
1616
||| the rest of the list, of length `len`.
17-
(::) : (1 x : elem) -> (1 xs : Vect len elem) -> Vect (S len) elem
17+
(::) : (x : elem) -> (xs : Vect len elem) -> Vect (S len) elem
1818

1919
-- Hints for interactive editing
2020
%name Vect xs,ys,zs,ws
@@ -101,7 +101,7 @@ index (FS k) (_::xs) = index k xs
101101
||| insertAt 1 8 [1,2,3,4]
102102
||| ```
103103
public export
104-
insertAt : (1 idx : Fin (S len)) -> (1 x : elem) -> (1 xs : Vect len elem) -> Vect (S len) elem
104+
insertAt : (idx : Fin (S len)) -> (x : elem) -> (xs : Vect len elem) -> Vect (S len) elem
105105
insertAt FZ y xs = y :: xs
106106
insertAt (FS k) y (x::xs) = x :: insertAt k y xs
107107

@@ -145,7 +145,7 @@ updateAt (FS k) f (x::xs) = x :: updateAt k f xs
145145
||| [1,2,3,4] ++ [5,6]
146146
||| ```
147147
public export
148-
(++) : (1 xs : Vect m elem) -> (1 ys : Vect n elem) -> Vect (m + n) elem
148+
(++) : (xs : Vect m elem) -> (ys : Vect n elem) -> Vect (m + n) elem
149149
(++) [] ys = ys
150150
(++) (x::xs) ys = x :: xs ++ ys
151151

@@ -207,9 +207,9 @@ merge = mergeBy compare
207207
||| reverse [1,2,3,4]
208208
||| ```
209209
public export
210-
reverse : (1 xs : Vect len elem) -> Vect len elem
210+
reverse : (xs : Vect len elem) -> Vect len elem
211211
reverse xs = go [] xs
212-
where go : (1 _ : Vect n elem) -> (1 _ : Vect m elem) -> Vect (n+m) elem
212+
where go : Vect n elem -> Vect m elem -> Vect (n+m) elem
213213
go {n} acc [] = rewrite plusZeroRightNeutral n in acc
214214
go {n} {m=S m} acc (x :: xs) = rewrite sym $ plusSuccRightSucc n m
215215
in go (x::acc) xs
@@ -244,7 +244,7 @@ toVect (S k) (x :: xs)
244244
toVect _ _ = Nothing
245245

246246
public export
247-
fromList' : (1 xs : Vect len elem) -> (1 l : List elem) -> Vect (length l + len) elem
247+
fromList' : (xs : Vect len elem) -> (l : List elem) -> Vect (length l + len) elem
248248
fromList' ys [] = ys
249249
fromList' {len} ys (x::xs) =
250250
rewrite (plusSuccRightSucc (length xs) len) in
@@ -258,7 +258,7 @@ fromList' {len} ys (x::xs) =
258258
||| fromList [1,2,3,4]
259259
||| ```
260260
public export
261-
fromList : (1 l : List elem) -> Vect (length l) elem
261+
fromList : (xs : List elem) -> Vect (length xs) elem
262262
fromList l =
263263
rewrite (sym $ plusZeroRightNeutral (length l)) in
264264
reverse $ fromList' [] l
@@ -283,16 +283,13 @@ zipWith f (x::xs) (y::ys) = f x y :: zipWith f xs ys
283283

284284
||| Linear version
285285
public export
286-
lzipWith : (f : (1 _ : a) -> (1 _ : b) -> c)
287-
-> (1 _ : Vect n a)
288-
-> (1 _ : Vect n b)
289-
-> Vect n c
286+
lzipWith : (f : a -> b -> c) -> Vect n a -> Vect n b -> Vect n c
290287
lzipWith _ [] [] = []
291288
lzipWith f (x::xs) (y::ys) = f x y :: lzipWith f xs ys
292289

293290
||| Extensional correctness lemma
294291
export
295-
lzipWithSpec : (f : (1 _ : a) -> (1 _ : b) -> c)
292+
lzipWithSpec : (f : a -> b -> c)
296293
-> (xs : Vect n a) -> (ys : Vect n b)
297294
-> lzipWith f xs ys = zipWith f xs ys
298295
lzipWithSpec _ [] [] = Refl
@@ -314,7 +311,7 @@ zipWith3 f (x::xs) (y::ys) (z::zs) = f x y z :: zipWith3 f xs ys zs
314311
||| zip (fromList [1,2,3,4]) (fromList [1,2,3,4])
315312
||| ```
316313
public export
317-
zip : (1 xs : Vect n a) -> (1 ys : Vect n b) -> Vect n (a, b)
314+
zip : (xs : Vect n a) -> (ys : Vect n b) -> Vect n (a, b)
318315
zip [] [] = []
319316
zip (x::xs) (y::ys) = (x, y) :: zip xs ys
320317

@@ -324,7 +321,7 @@ zip (x::xs) (y::ys) = (x, y) :: zip xs ys
324321
||| zip3 (fromList [1,2,3,4]) (fromList [1,2,3,4]) (fromList [1,2,3,4])
325322
||| ```
326323
public export
327-
zip3 : (1 xs : Vect n a) -> (1 ys : Vect n b) -> (1 zs : Vect n c) -> Vect n (a, b, c)
324+
zip3 : (xs : Vect n a) -> (ys : Vect n b) -> (zs : Vect n c) -> Vect n (a, b, c)
328325
zip3 [] [] [] = []
329326
zip3 (x::xs) (y::ys) (z::zs) = (x, y, z) :: zip3 xs ys zs
330327

@@ -334,7 +331,7 @@ zip3 (x::xs) (y::ys) (z::zs) = (x, y, z) :: zip3 xs ys zs
334331
||| unzip (fromList [(1,2), (1,2)])
335332
||| ```
336333
public export
337-
unzip : (1 xs : Vect n (a, b)) -> (Vect n a, Vect n b)
334+
unzip : (xs : Vect n (a, b)) -> (Vect n a, Vect n b)
338335
unzip [] = ([], [])
339336
unzip ((l, r)::xs) = let (lefts, rights) = unzip xs
340337
in (l::lefts, r::rights)
@@ -345,7 +342,7 @@ unzip ((l, r)::xs) = let (lefts, rights) = unzip xs
345342
||| unzip3 (fromList [(1,2,3), (1,2,3)])
346343
||| ```
347344
public export
348-
unzip3 : (1 xs : Vect n (a, b, c)) -> (Vect n a, Vect n b, Vect n c)
345+
unzip3 : (xs : Vect n (a, b, c)) -> (Vect n a, Vect n b, Vect n c)
349346
unzip3 [] = ([], [], [])
350347
unzip3 ((l,c,r)::xs) = let (lefts, centers, rights) = unzip3 xs
351348
in (l::lefts, c::centers, r::rights)
@@ -436,7 +433,7 @@ implementation Foldable (Vect n) where
436433
||| concat [[1,2,3], [4,5,6]]
437434
||| ```
438435
public export
439-
concat : (1 xss : Vect m (Vect n elem)) -> Vect (m * n) elem
436+
concat : (xss : Vect m (Vect n elem)) -> Vect (m * n) elem
440437
concat [] = []
441438
concat (v::vs) = v ++ Vect.concat vs
442439

@@ -810,7 +807,7 @@ vectToMaybe (x::xs) = Just x
810807
||| catMaybes [Just 1, Just 2, Nothing, Nothing, Just 5]
811808
||| ```
812809
public export
813-
catMaybes : (1 xs : Vect n (Maybe elem)) -> (p ** Vect p elem)
810+
catMaybes : (xs : Vect n (Maybe elem)) -> (p ** Vect p elem)
814811
catMaybes [] = (_ ** [])
815812
catMaybes (Nothing::xs) = catMaybes xs
816813
catMaybes ((Just j)::xs) =
@@ -845,7 +842,7 @@ range {len=S _} = FZ :: map FS range
845842
||| transpose [[1,2], [3,4], [5,6], [7,8]]
846843
||| ```
847844
public export
848-
transpose : {n : _} -> (1 array : Vect m (Vect n elem)) -> Vect n (Vect m elem)
845+
transpose : {n : _} -> (array : Vect m (Vect n elem)) -> Vect n (Vect m elem)
849846
transpose [] = replicate _ [] -- = [| [] |]
850847
transpose (x :: xs) = lzipWith (::) x (transpose xs) -- = [| x :: xs |]
851848

libs/contrib/Control/Linear/LIO.idr

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ Applicative io => Applicative (L io) where
9595

9696
export
9797
(Applicative m, LinearBind m) => Monad (L m) where
98-
(>>=) = Bind
98+
(>>=) a k = Bind a k
9999

100100
-- prioritise this one for concrete LIO, so we get the most useful
101101
-- linearity annotations.

libs/contrib/Data/HVect.idr

+7-7
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ data HVect : Vect k Type -> Type where
2121
||| 1
2222
||| ```
2323
public export
24-
index : (1 i : Fin k) -> (1 _ : HVect ts) -> index i ts
24+
index : (i : Fin k) -> HVect ts -> index i ts
2525
index FZ (x :: xs) = x
2626
index (FS j) (x :: xs) = index j xs
2727

@@ -32,7 +32,7 @@ index (FS j) (x :: xs) = index j xs
3232
||| ["string"]
3333
||| ```
3434
public export
35-
deleteAt : (1 i : Fin (S l)) -> (1 _ : HVect ts) -> HVect (deleteAt i ts)
35+
deleteAt : (i : Fin (S l)) -> HVect ts -> HVect (deleteAt i ts)
3636
deleteAt FZ (x :: xs) = xs
3737
deleteAt (FS FZ) (x :: (y :: xs)) = x :: xs
3838
deleteAt (FS (FS j)) (x :: (y :: xs)) = x :: deleteAt (FS j) (y :: xs)
@@ -44,7 +44,7 @@ deleteAt (FS (FS j)) (x :: (y :: xs)) = x :: deleteAt (FS j) (y :: xs)
4444
||| ["firstString", "string"]
4545
||| ```
4646
public export
47-
replaceAt : (1 i : Fin k) -> t -> (1 _ : HVect ts) -> HVect (replaceAt i t ts)
47+
replaceAt : (i : Fin k) -> t -> HVect ts -> HVect (replaceAt i t ts)
4848
replaceAt FZ y (x :: xs) = y :: xs
4949
replaceAt (FS j) y (x :: xs) = x :: replaceAt j y xs
5050

@@ -55,7 +55,7 @@ replaceAt (FS j) y (x :: xs) = x :: replaceAt j y xs
5555
||| [True, "string"]
5656
||| ```
5757
public export
58-
updateAt : (1 i : Fin k) -> (index i ts -> t) -> (1 _ : HVect ts) -> HVect (replaceAt i t ts)
58+
updateAt : (i : Fin k) -> (index i ts -> t) -> HVect ts -> HVect (replaceAt i t ts)
5959
updateAt FZ f (x :: xs) = f x :: xs
6060
updateAt (FS j) f (x :: xs) = x :: updateAt j f xs
6161

@@ -66,7 +66,7 @@ updateAt (FS j) f (x :: xs) = x :: updateAt j f xs
6666
||| [1, "string"]
6767
||| ```
6868
public export
69-
(++) : (1 _ : HVect ts) -> HVect us -> HVect (ts ++ us)
69+
(++) : HVect ts -> HVect us -> HVect (ts ++ us)
7070
(++) [] ys = ys
7171
(++) (x :: xs) ys = x :: (xs ++ ys)
7272

@@ -79,11 +79,11 @@ public export
7979
(x :: xs) == (y :: ys) = x == y && xs == ys
8080

8181
public export
82-
consInjective1 : {0 xs, ys: HVect ts} -> {0 x, y: a} -> (1 _ : x :: xs = y :: ys) -> x = y
82+
consInjective1 : {0 xs, ys: HVect ts} -> {0 x, y: a} -> (x :: xs = y :: ys) -> x = y
8383
consInjective1 Refl = Refl
8484

8585
public export
86-
consInjective2 : {0 xs, ys: HVect ts} -> {0 x, y: a} -> (1 _ : x :: xs = y :: ys) -> xs = ys
86+
consInjective2 : {0 xs, ys: HVect ts} -> {0 x, y: a} -> (x :: xs = y :: ys) -> xs = ys
8787
consInjective2 Refl = Refl
8888

8989
public export

libs/contrib/Data/Linear/Array.idr

+6-5
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ interface Array arr => MArray arr where
1919
-- Array is unchanged if the index is out of bounds
2020
write : (1 _ : arr t) -> Int -> t -> arr t
2121

22-
mread : (1 _ : arr t) -> Int -> LPair (Maybe t) (arr t)
23-
msize : (1 _ : arr t) -> LPair Int (arr t)
22+
mread : (1 _ : arr t) -> Int -> Res (Maybe t) (const (arr t))
23+
msize : (1 _ : arr t) -> Res Int (const (arr t))
2424

2525
export
2626
data IArray : Type -> Type where
@@ -57,16 +57,17 @@ Array IArray where
5757
size (MkIArray a) = max a
5858

5959
export
60-
copyArray : MArray arr => (newsize : Int) -> (1 _ : arr t) -> (arr t, arr t)
60+
copyArray : MArray arr => (newsize : Int) -> (1 _ : arr t) ->
61+
LPair (arr t) (arr t)
6162
copyArray newsize a
6263
= let size # a = msize a in
6364
newArray newsize $
6465
(\a' => copyContent (min (newsize - 1) (size - 1)) a a')
6566
where
66-
copyContent : Int -> (1 _ : arr t) -> (1 _ : arr t) -> (arr t, arr t)
67+
copyContent : Int -> (1 _ : arr t) -> (1 _ : arr t) -> LPair (arr t) (arr t)
6768
copyContent pos a a'
6869
= if pos < 0
69-
then (a, a')
70+
then a # a'
7071
else let val # a = mread a pos
7172
1 a' = case val of
7273
Nothing => a'

0 commit comments

Comments
 (0)