> data Usage = Once | Many > data Use : Usage -> (Type -> Type) -> Type -> Type where > Pure : (1 x : a) -> Use t m a > BindOnce : (1 act : Use Once m a) -> (1 k : (1 x : a) -> Use t m b) -> Use t m b > BindMany : (1 act : Use Many m a) -> (1 k : (x : a) -> Use t m b) -> Use t m b > contType : (Type -> Type) -> Usage -> Usage -> Type -> Type -> Type > contType m Once q a b = ((1 x : a) -> Use q m b) > contType m Many q a b = ((x : a) -> Use q m b) > (>>=) : {p : _} -> (1 f : Use p m a) -> (1 k : contType m p q a b) -> Use q m b > (>>=) {p = Once} = BindOnce > (>>=) {p = Many} = BindMany > pure : (1 x : a) -> Use t m a > pure = Pure > One : (Type -> Type) -> Type -> Type > One = Use Once > Any : (Type -> Type) -> Type -> Type > Any = Use Many > data DoorState = Closed | Open > data Door : DoorState -> Type where > MkDoor : (isOpen : Bool) -> Door (if isOpen then Open else Closed) > newDoor : One m (Door Closed) > newDoor = pure (MkDoor False) > knock : (1 d : Door Closed) -> One m (Door Closed) > openDoor : (1 d : Door Closed) -> > One m (Res Bool (\r => Door (if r then Open else Closed))) > closeDoor : (1 d : Door Open) -> One m (Door Closed) > deleteDoor : (1 d : Door Closed) -> Any m () > doorProg : Any m () > doorProg > = do d <- newDoor > r <- openDoor d > let x = 42 > case r of > what => ?now > doorProg2 : Any m () > doorProg2 > = do d <- newDoor > r <- openDoor d > let x = 42 > case r of > (res # d) => ?now_1 > doorProg3 : Any m () > doorProg3 > = do d <- newDoor > r <- openDoor d > let x = 42 > case r of > (True # d) => ?now_2 > (False # d) => ?now_3