import Control. Concurrent
data Knob = Turned | Unturned
data ExtensionDoor e = Opened Knob e | Closed Knob e
class Door a where
isOpen
, isClose
, canBeOpened
:: a
-> IO Bool pull
, push
, knobTurn
, knobUnturn
:: a
-> IO ( )
isClose door
= return . not =<< ( isOpen door
)
type Ordinary = ( )
newtype OrdinaryDoor = OrdinaryDoor ( MVar ( ExtensionDoor Ordinary) )
instance Door ( OrdinaryDoor) where
createDoor = do
m <- newMVar ( Closed Unturned ( ) )
isOpen ( OrdinaryDoor m) = do
door <- takeMVar m
putMVar m door
Opened _ _-> True
_ -> False
canBeOpened ( OrdinaryDoor m) = do
door <- takeMVar m
putMVar m door
Closed Turned _ -> True
_ -> False
pull ( OrdinaryDoor m) = do
_ <- takeMVar m
putMVar m ( Closed Unturned ( ) )
push ( OrdinaryDoor m) = do
door <- takeMVar m
putMVar m $ case door of
Closed Turned _ -> Opened Unturned ( )
_ -> door
knobTurn ( OrdinaryDoor m) = do
door <- takeMVar m
putMVar m $ case door of
Closed Unturned _ -> Closed Turned ( )
Opened Unturned _ -> Opened Turned ( )
_ -> door
knobUnturn ( OrdinaryDoor m) = do
door <- takeMVar m
putMVar m $ case door of
Closed Turned _ -> Closed Unturned ( )
_ -> door
test1 = do
door
<- createDoor
:: IO OrdinaryDoor
knobTurn door
putStrLn . ( "knobTurn door; canBeOpened door => " ++ ) . show =<< canBeOpened door
knobUnturn door
putStrLn . ( "knobUnturn door; canBeOpened door => " ++ ) . show =<< canBeOpened door
push door
putStrLn . ( "push door; isOpen door => " ++ ) . show =<< isOpen door
knobTurn door
push door
putStrLn . ( "knobTurn door; push door; isOpen door => " ++ ) . show =<< isOpen door
pull door
putStrLn . ( "push door; isOpen door => " ++ ) . show =<< isOpen door
putStrLn . ( "canBeOpened door => " ++ ) . show =<< canBeOpened door
main = test1
aW1wb3J0IENvbnRyb2wuQ29uY3VycmVudAppbXBvcnQgQ29udHJvbC5Nb25hZAoKZGF0YSBLbm9iID0gVHVybmVkIHwgVW50dXJuZWQKZGF0YSBFeHRlbnNpb25Eb29yIGUgPSBPcGVuZWQgS25vYiBlIHwgQ2xvc2VkIEtub2IgZQoKY2xhc3MgRG9vciBhIHdoZXJlCiAgY3JlYXRlRG9vciA6OiBJTyBhCiAgaXNPcGVuLCBpc0Nsb3NlLCBjYW5CZU9wZW5lZCA6OiBhIC0+IElPIEJvb2wKICBwdWxsLCBwdXNoLCBrbm9iVHVybiwga25vYlVudHVybiA6OiBhIC0+IElPICgpCgogIGlzQ2xvc2UgZG9vciA9IHJldHVybiAuIG5vdCA9PDwgKGlzT3BlbiBkb29yKQoKdHlwZSBPcmRpbmFyeSA9ICgpCm5ld3R5cGUgT3JkaW5hcnlEb29yID0gT3JkaW5hcnlEb29yIChNVmFyIChFeHRlbnNpb25Eb29yIE9yZGluYXJ5KSkKCmluc3RhbmNlIERvb3IgKE9yZGluYXJ5RG9vcikgd2hlcmUKICBjcmVhdGVEb29yID0gZG8KICAgIG0gPC0gbmV3TVZhciAoQ2xvc2VkIFVudHVybmVkICgpKQogICAgcmV0dXJuIChPcmRpbmFyeURvb3IgbSkKICBpc09wZW4gKE9yZGluYXJ5RG9vciBtKSA9IGRvCiAgICBkb29yIDwtIHRha2VNVmFyIG0KICAgIHB1dE1WYXIgbSBkb29yCiAgICByZXR1cm4gJCBjYXNlIGRvb3Igb2YKICAgICAgT3BlbmVkIF8gXy0+IFRydWUKICAgICAgXyAtPiBGYWxzZQogIAogIGNhbkJlT3BlbmVkIChPcmRpbmFyeURvb3IgbSkgPSBkbwogICAgZG9vciA8LSB0YWtlTVZhciBtCiAgICBwdXRNVmFyIG0gZG9vcgogICAgcmV0dXJuICQgY2FzZSBkb29yIG9mCiAgICAgIENsb3NlZCBUdXJuZWQgXyAtPiBUcnVlCiAgICAgIF8gLT4gRmFsc2UKCiAgcHVsbCAoT3JkaW5hcnlEb29yIG0pID0gZG8KICAgIF8gPC0gdGFrZU1WYXIgbQogICAgcHV0TVZhciBtIChDbG9zZWQgVW50dXJuZWQgKCkpCgogIHB1c2ggKE9yZGluYXJ5RG9vciBtKSA9IGRvCiAgICBkb29yIDwtIHRha2VNVmFyIG0KICAgIHB1dE1WYXIgbSAkIGNhc2UgZG9vciBvZgogICAgICBDbG9zZWQgVHVybmVkIF8gLT4gT3BlbmVkIFVudHVybmVkICgpCiAgICAgIF8gLT4gZG9vcgoKICBrbm9iVHVybiAoT3JkaW5hcnlEb29yIG0pID0gZG8KICAgIGRvb3IgPC0gdGFrZU1WYXIgbQogICAgcHV0TVZhciBtICQgY2FzZSBkb29yIG9mCiAgICAgIENsb3NlZCBVbnR1cm5lZCBfIC0+IENsb3NlZCBUdXJuZWQgKCkKICAgICAgT3BlbmVkIFVudHVybmVkIF8gLT4gT3BlbmVkIFR1cm5lZCAoKQogICAgICBfIC0+IGRvb3IKCiAga25vYlVudHVybiAoT3JkaW5hcnlEb29yIG0pID0gZG8KICAgIGRvb3IgPC0gdGFrZU1WYXIgbQogICAgcHV0TVZhciBtICQgY2FzZSBkb29yIG9mCiAgICAgIENsb3NlZCBUdXJuZWQgXyAtPiBDbG9zZWQgVW50dXJuZWQgKCkKICAgICAgXyAtPiBkb29yCgoKdGVzdDEgOjogSU8gKCkKdGVzdDEgPSBkbwogIGRvb3IgPC0gY3JlYXRlRG9vciA6OiBJTyBPcmRpbmFyeURvb3IKICBwdXRTdHJMbiAiZG9vciBpcyBhIERvb3IiCgogIGtub2JUdXJuIGRvb3IgCiAgcHV0U3RyTG4gLiAoImtub2JUdXJuIGRvb3I7IGNhbkJlT3BlbmVkIGRvb3IgPT4gIiArKykgLiBzaG93ID08PCBjYW5CZU9wZW5lZCBkb29yCgogIGtub2JVbnR1cm4gZG9vcgogIHB1dFN0ckxuIC4gKCJrbm9iVW50dXJuIGRvb3I7IGNhbkJlT3BlbmVkIGRvb3IgPT4gIiArKykgLiBzaG93ID08PCBjYW5CZU9wZW5lZCBkb29yCgogIHB1c2ggZG9vcgogIHB1dFN0ckxuIC4gKCJwdXNoIGRvb3I7IGlzT3BlbiBkb29yID0+ICIgKyspIC4gc2hvdyA9PDwgaXNPcGVuIGRvb3IKCiAga25vYlR1cm4gZG9vcgogIHB1c2ggZG9vcgogIHB1dFN0ckxuIC4gKCJrbm9iVHVybiBkb29yOyBwdXNoIGRvb3I7IGlzT3BlbiBkb29yID0+ICIgKyspIC4gc2hvdyA9PDwgaXNPcGVuIGRvb3IKCiAgcHVsbCBkb29yCiAgcHV0U3RyTG4gLiAoInB1c2ggZG9vcjsgaXNPcGVuIGRvb3IgPT4gIiArKykgLiBzaG93ID08PCBpc09wZW4gZG9vcgogIHB1dFN0ckxuIC4gKCJjYW5CZU9wZW5lZCBkb29yID0+ICIgKyspIC4gc2hvdyA9PDwgY2FuQmVPcGVuZWQgZG9vcgoKbWFpbiA6OiBJTyAoKQptYWluID0gdGVzdDEK