0 | module Control.Linear.LIO
2 | import public Data.Linear.Notation
8 | interface LinearBind io where
9 | bindL : io a -@ (a -> io b) -@ io b
17 | data Usage = None | Linear | Unrestricted
22 | fromInteger : (x : Integer) -> {auto _ : Either (x = 0) (x = 1)} -> Usage
23 | fromInteger 0 = None
24 | fromInteger 1 = Linear
25 | fromInteger x = Unrestricted
28 | 0 ContType : (Type -> Type) -> Usage -> Usage -> Type -> Type -> Type
37 | data L : (io : Type -> Type) ->
38 | {default Unrestricted use : Usage} ->
39 | (ty : Type) -> Type where
43 | Pure0 : (0 _ : a) -> L io {use=0} a
44 | Pure1 : (1 _ : a) -> L io {use=1} a
48 | Action : (1 _ : io a) -> L io {use} a
49 | Bind : {u_act : _} ->
50 | (1 _ : L io {use=u_act} a) ->
51 | (1 _ : ContType io u_act u_k a b) ->
55 | L0 : (io : Type -> Type) -> (ty : Type) -> Type
56 | L0 io ty = L io {use = 0} ty
59 | L1 : (io : Type -> Type) -> (ty : Type) -> Type
60 | L1 io ty = L io {use = 1} ty
62 | ContType io None u_k a b = (0 _ : a) -> L io {use=u_k} b
63 | ContType io Linear u_k a b = (1 _ : a) -> L io {use=u_k} b
64 | ContType io Unrestricted u_k a b = a -> L io {use=u_k} b
66 | RunCont : Usage -> Type -> Type -> Type
67 | RunCont None t b = (0 _ : t) -> b
68 | RunCont Linear t b = (1 _ : t) -> b
69 | RunCont Unrestricted t b = t -> b
76 | L io {use} a -@ RunCont use a (io b) -@ io b
77 | runK (Pure0 x) k = k x
78 | runK (Pure1 x) k = k x
79 | runK (PureW x) k = k x
80 | runK {use = None} (Action x) k = bindL x $
\x' => k x'
81 | runK {use = Linear} (Action x) k = bindL x $
\x' => k x'
82 | runK {use = Unrestricted} (Action x) k = bindL x $
\x' => k x'
83 | runK (Bind {u_act = None} act next) k = runK act (\x => runK (next x) k)
84 | runK (Bind {u_act = Linear} act next) k = runK act (\x => runK (next x) k)
85 | runK (Bind {u_act = Unrestricted} act next) k = runK act (\x => runK (next x) k)
90 | run : Applicative io => LinearBind io =>
92 | run prog = runK prog pure
95 | Functor io => Functor (L io) where
96 | map fn act = Bind act $
\a' => PureW (fn a')
99 | Applicative io => Applicative (L io) where
107 | (Applicative m, LinearBind m) => Monad (L m) where
108 | (>>=) a k = Bind a k
113 | (>>=) : {u_act : _} ->
115 | L io {use=u_act} a -@
116 | ContType io u_act u_k a b -@ L io {use=u_k} b
120 | delay : {u_act : _} -> L io {use=u_k} b -@ ContType io u_act u_k () b
121 | delay mb = case u_act of
123 | Linear => \ () => mb
124 | Unrestricted => \ _ => mb
127 | (>>) : {u_act : _} ->
129 | L io {use=u_act} () -@
130 | L io {use=u_k} b -@ L io {use=u_k} b
131 | ma >> mb = ma >>= delay mb
134 | pure0 : (0 x : a) -> L io {use=0} a
138 | pure1 : a -@ L io {use=1} a
145 | bang : L IO t -@ L1 IO (!* t)
146 | bang io = io >>= \ a => pure1 (MkBang a)
149 | (LinearBind io, HasLinearIO io) => HasLinearIO (L io) where
150 | liftIO1 p = Action (liftIO1 p)
153 | LinearIO : (Type -> Type) -> Type
154 | LinearIO io = (LinearBind io, HasLinearIO io)
158 | die1 : LinearIO io => String -> L1 io a