
Brilliant! That's what I was looking for. Thanks for all the replies.
Sometimes, I suspect that Haskell not only makes easier of the hard things for
imperative programming languages but also makes harder of some easy things.
Roman Cheplyaka
* Steve Horne
[2012-02-04 11:54:44+0000] On 04/02/2012 08:46, MigMit wrote:
Well, if you want that in production, not for debugging purposes, you should change the type signature of mergesort so that it uses some monad. Printing requires IO monad; however, I would advise to collect all intermediate results using Writer monad, and print them afterwards:
mergesort [] = return [] mergesort [x] = return [x] mergesort xs = do tell [xs] -- that's right, "[xs]", not "xs" let (as, bs) = splitAt (length xs `quot` 2) xs liftM2 merge (mergesort as) (mergesort bs) Also, don't forget that IO actions are values too. IOW, your list of intermediate results can be a list of IO actions, effectively deferring their "execution" until later.
No need to keep them in a list -- you can compose them as you go, while still deferring the execution.
import Data.Monoid import Control.Monad.Writer
newtype O = O (IO ())
instance Monoid O where mempty = O $ return () mappend (O a) (O b) = O $ a >> b
mergesort [] = return [] mergesort [x] = return [x] mergesort xs = do trace xs let (as, bs) = splitAt (length xs `quot` 2) xs liftM2 merge (mergesort as) (mergesort bs) where trace = tell . O . print
main = let (_, O trace) = runWriter $ mergesort [3,1,4,2,10,8,4,7,6] in trace
-- Qi Qi