Re: [Haskell-cafe] Proper way to write this
Quoth Pupeno <pupeno@pupeno.com>: | I have this piece of code: What do you think about this? may_ = maybe (return ()) (\ _ -> f) stopDaytimeServer dts = do may_ (killServer (ss dts)) (streamPort dts) may_ (killServer (ds dts)) (dgramPort dts) | PS: I have a worse case: I don't think it will be too much worse. I would not try to combine the struct updates, in the "both" case -- it doesn't buy you anything, and pulls you into duplication you don't want. Donn Cave, donn@drizzle.com | stopDaytimeServer dts = | case dts of | DaytimeServer {streamPort = Just _, dgramPort = Just _} -> do | killServer (ss dts) | killServer (ds dts) | DaytimeServer {streamPort = Just _, dgramPort = Nothing} -> do | killServer (ss dts) | DaytimeServer {streamPort = Nothing, dgramPort = Just _} -> do | killServer (ds dts) | -- | Having a 'DaytimeServer', run it according to its specifications. | runDaytimeServer :: DaytimeServer -> IO DaytimeServer | runDaytimeServer dts = | case dts of | DaytimeServer {streamPort = Just _, dgramPort = Just _} -> do | ss <- runDgramDaytimeServer dts | ds <- runStreamDaytimeServer dts | return dts{ss = ss, ds = ds} | DaytimeServer {streamPort = Just _, dgramPort = Nothing} -> do | ss <- runStreamDaytimeServer dts | return dts{ss = ss} | DaytimeServer {streamPort = Nothing, dgramPort = Just _} -> do | ds <- runDgramDaytimeServer dts | return dts{ds = ds}
On Monday 26 December 2005 02:41, Donn Cave wrote:
I don't think it will be too much worse. I would not try to combine the struct updates, in the "both" case -- it doesn't buy you anything, and pulls you into duplication you don't want. What about this
runDaytimeServer :: DaytimeServer -> IO DaytimeServer runDaytimeServer dts = do dts' <- runStreamDaytimeServer dts dts' <- runDgramDaytimeServer dts' return dts' ? I moved the structure update of dts into run_DaytimeServer. Thanks. -- Pupeno <pupeno@pupeno.com> (http://pupeno.com)
Pupeno wrote:
On Monday 26 December 2005 02:41, Donn Cave wrote:
I don't think it will be too much worse. I would not try to combine the struct updates, in the "both" case -- it doesn't buy you anything, and pulls you into duplication you don't want.
What about this
runDaytimeServer :: DaytimeServer -> IO DaytimeServer runDaytimeServer dts = do dts' <- runStreamDaytimeServer dts dts' <- runDgramDaytimeServer dts' return dts'
runDaytimeServer dts = runStreamDaytimeServer dts >>= runDgramDaytimeServer Don't write a <- foo return a write foo instead. -- WBR, Max Vasin.
Max Vasin wrote:
Pupeno wrote:
What about this
runDaytimeServer :: DaytimeServer -> IO DaytimeServer runDaytimeServer dts = do dts' <- runStreamDaytimeServer dts dts' <- runDgramDaytimeServer dts' return dts'
runDaytimeServer dts = runStreamDaytimeServer dts >>= runDgramDaytimeServer
I have seen this pattern many times, and I am surprised it is not present in Control.Monad. (>>-) :: (a -> m b) -> (b -> m c) -> a -> m c (>>-) f g a = f a >>= g Your code becomes runDaytimeServer = runStreamDaytimeServer >>- runDgramDaytimeServer This >>- operator is a very natural "composition" operator in a Monad, at least to me. It seems to be the most obvious counter-part to '.'. But I could not find anything with that signature in the libraries -- or did I miss it? [And >>- is typographically sub-optimal, but I can't think of something better]. Jacques
participants (4)
-
Donn Cave -
Jacques Carette -
Max Vasin -
Pupeno