2020-05-19 20:25:18 +03:00
|
|
|
module StoreL
|
|
|
|
|
|
|
|
import Control.App
|
|
|
|
import Control.App.Console
|
|
|
|
|
|
|
|
data Access = LoggedOut | LoggedIn
|
|
|
|
data Store : Access -> Type where
|
|
|
|
MkStore : (secret : String) -> Store a
|
|
|
|
|
|
|
|
interface StoreI e where
|
|
|
|
connect : (1 prog : (1 d : Store LoggedOut) ->
|
|
|
|
App {l} e ()) -> App {l} e ()
|
|
|
|
disconnect : (1 d : Store LoggedOut) -> App {l} e ()
|
|
|
|
|
|
|
|
Has [Console] e => StoreI e where
|
|
|
|
connect f
|
|
|
|
= let (>>=) = bindL in
|
2021-02-24 14:07:16 +03:00
|
|
|
let (>>) = seqL in
|
2020-05-19 20:25:18 +03:00
|
|
|
do putStrLn "Connected"
|
|
|
|
f (MkStore "xyzzy")
|
|
|
|
disconnect (MkStore _)
|
2021-02-24 14:07:16 +03:00
|
|
|
= do ignore $ putStrLn "Disconnected"
|
2020-05-19 20:25:18 +03:00
|
|
|
|
|
|
|
login : (1 s : Store LoggedOut) -> (password : String) ->
|
|
|
|
Res Bool (\ok => Store (if ok then LoggedIn else LoggedOut))
|
|
|
|
login (MkStore secret) password
|
2020-07-08 02:56:12 +03:00
|
|
|
= password == "Mornington Crescent" # MkStore secret
|
2020-05-19 20:25:18 +03:00
|
|
|
|
|
|
|
logout : (1 s : Store LoggedIn) -> Store LoggedOut
|
|
|
|
logout (MkStore secret) = MkStore secret
|
|
|
|
|
|
|
|
storeProg : Has [Console, StoreI] e => App e ()
|
|
|
|
storeProg
|
|
|
|
= let (>>=) = bindL in
|
2021-02-24 14:07:16 +03:00
|
|
|
let (>>) = seqL in
|
2020-05-19 20:25:18 +03:00
|
|
|
do putStr "Password: "
|
|
|
|
password <- Console.getStr
|
|
|
|
connect $ \s =>
|
2020-06-12 13:18:12 +03:00
|
|
|
do let True # s = login s password
|
|
|
|
| False # s => do putStrLn "Incorrect password"
|
|
|
|
disconnect s
|
2020-05-19 20:25:18 +03:00
|
|
|
putStrLn "Door opened"
|
2020-07-08 02:56:12 +03:00
|
|
|
let s = logout s
|
2020-05-19 20:25:18 +03:00
|
|
|
putStrLn "Door closed"
|
|
|
|
disconnect s
|
|
|
|
|
|
|
|
foo : IO ()
|
|
|
|
foo = run storeProg
|