[Haskell-beginners] Mixing IO and other monads
Brian Victor
homeusenet4 at brianhv.org
Sun Aug 29 18:56:06 EDT 2010
I've managed to create the sort of nested case code that all the monad
tutorials warn you against. I haven't found a way to work myself out of
it, though. If I've understood monad transformers conceptually, this
seems like the sort of thing they'd be good for, but I don't know how to
actually make what I need.
Here's the code I have. getDefaultInputDeviceID and
getDefaultOutputDeviceID are from PortMidi, and return IO (Maybe Int).
openInput and openOutput return IO (Either PMStream PMError). At this
point, I'd be happy to get the second half of the function refactored
into monads.
main :: IO ()
main = do
initialize
ideviceId <- getDefaultInputDeviceID
case ideviceId of
Nothing -> putStrLn "No default input device"
Just inputDeviceId -> do
odeviceId <- getDefaultOutputDeviceID
case odeviceId of
Nothing -> putStrLn "No default output device"
Just outputDeviceId -> do
openInputResult <- openInput inputDeviceId
case openInputResult of
Right err -> putStrLn $ show err
Left inputStream -> do
openOutputResult <- openOutput outputDeviceId 0
case openOutputResult of
Right err -> putStrLn $ show err
Left outputStream -> runTranslationLoop inputStream outputStream
It seems like I ought to be able to change the second half of the
function to something like this:
openStreamsAndLoop :: (Num a) => a -> a -> IO (Maybe err)
openStreamsAndLoop inputDeviceId outputDeviceId = do
inputStream <- openInput inputDeviceId
outputStream <- openOutput outputDeviceId 0
runTranslationLoop inputStream outputStream
return Nothing
But how do I create an IO (Maybe err) monad?
--
Brian
More information about the Beginners
mailing list