> 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
