On Wed, Jan 31, 2007 at 07:46:15PM +0300, Bulat Ziganshin wrote: > Wednesday, January 31, 2007, 12:01:16 PM, you wrote: > > >> there are also many other similar issues, such as lack of good syntax > >> for "for", "while", "break" and other well-known statements, > > > On the other hand you have an ability to define your own control > > structures. > > i have a lot, but their features are limited, both in terms of > automatic lifting and overall syntax. let's consider > > while (hGetBuf h buf bufsize == bufsize) > crc := updateCrc crc buf bufsize > break if crc==0 > print crc
A direct translation could look like this: whileM c b = do { x <- c; when x (b >> whileM c b) } f h buf = flip runContT return $ do callCC $ \break -> do flip execStateT 0 $ do whileM (liftIO (liftM (== bufsize) (hGetBuf h buf bufsize))) $ do do crc <- get crc' <- liftIO (updateCrc crc buf bufsize) put crc' crc <- get when (crc == 0) (lift (break crc)) liftIO (print crc) Which, admittedly, is much more lengthy. If we assume that hGetBuf, updateCrc and print can work in any MonadIO, and we define inContT x = flip runContT return x then it becomes slightly shorter: inContT $ callCC $ \break -> do flip execStateT 0 $ do whileM (liftM (== bufsize) (hGetBuf h buf bufsize)) $ do do crc <- get crc' <- updateCrc crc buf bufsize put crc' crc <- get when (crc == 0) (lift (break crc)) Let's define: modifyM f = do x <- get x' <- f x put x' and change the order of parametrs in updateCrc. We get: inContT $ callCC $ \break -> do flip execStateT 0 $ do whileM (liftM (== bufsize) (hGetBuf h buf bufsize)) $ do modifyM (updateCrc buf bufsize) crc <- get when (crc == 0) (lift (break crc)) print crc > how this can be expressed in Haskell, without losing clarity? I think it's quite clear what it does. > > "inability" is an exaggeration - you can use the ContT monad > > transformer, which even allows you to choose how "high" you > > want to jump. But you probably already know this and just want to point > > that it is cumbersome? > > don't know and don't want to use such a hard way. I gave an example above. You can "break" with a return value, so it seem it's what you want. > there is a simpler solution, but it still requires to write more > boilerplate code than C: > > res <- doSomething > if isLeft res then return$ fromLeft res else do > let (Right x) = res > ... Not simpler, but easier... and uglier. Somehow I don't like to solve problems on the level of programming language syntax. Best regards Tomasz _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe