[Haskell-beginners] How to structure an application?
Tilmann
t_gass at gmx.de
Sun Jun 28 14:03:37 UTC 2020
Hi,
I hope to get some advice on how to structure an application. So I
acquire a handle early on that I use all over the app, but I don't want
to pass the handle itself around, but wrap the handle with "commands"
that a) make a nicer api and/or b) only allow specific usecases of the
handle. I tried and failed to use MonadReader in a straightforward way
and now I'm wondering what options there are. Looking forward to your
feedback,
Best,
Tilmann
module Main where
import Control.Monad
import Control.Monad.Reader
import Graphics.UI.WX
import System.IO
-- imagine many more commands like this one
ping :: (MonadReader Handle m, MonadIO m) => m ()
ping = do
h <- ask
liftIO $ hPutStrLn h "ping"
main :: IO ()
main = do
let h = stdout -- in the real app, this handle isn't stdout of course
but opened separately
start $ runReaderT wxApp h
wxApp :: (MonadReader Handle m, MonadIO m) => m ()
wxApp = do
ping -- this works, but I don't need it here..
liftIO $ do
f <- frame [ ]
timer f [ interval := 1000
-- , on command := hputStrLn h "ping" -- this is what I try
to avoid
-- , on command := ping -- of course, this doesn't work, but
it would be so nice..
, enabled := True]
return ()
-- Alternatively
main2 :: IO ()
main2 = do
let h = stdout
start $ runReaderT wxApp2 (mkCommands h)
wxApp2 :: (MonadReader Commands m, MonadIO m) => m ()
wxApp2 = do
commands <- ask
liftIO $ do
f <- frame [ ]
timer f [ interval := 1000
, on command := ping2 commands
, enabled := True]
return ()
data Commands = Commands {
ping2 :: IO ()
-- .. many more
}
mkCommands :: Handle -> Commands
mkCommands h = Commands (hPutStrLn h "ping")
More information about the Beginners
mailing list