
Hello all, this was previously posted on Haskell Beginners, but only partially answered. In Sound.ALSA.Sequencer, there are a number of functions which together set up a midi environement (client, port, queue). They all have a type, where the last argument has a type like: (something.T -> IO a) i.e. *Main> :t SndSeq.withDefault SndSeq.withDefault :: SndSeq.OpenMode mode => SndSeq.BlockMode -> (SndSeq.T mode -> IO a) -> IO a *Main> :t Port.withSimple Port.withSimple :: SndSeq.T mode -> String -> Port.Cap -> Port.Type -> (Port.T -> IO a) -> IO a *Main> :t Queue.with Queue.with :: SndSeq.T mode -> (Queue.T -> IO a) -> IO a There is example code, where a full setup is created by a number of nested "do" blocks. The repeating pattern there is: something1 $ \x -> do something2 $ \y -> do something3 $ \z -> do What is this all about? I particularly would like to understand, when this parttern is needed and what determines the the number of nested "do" blocks. -- Martin