rjpj1998
rjpj1998

Reputation: 419

Breaking out of a forM_ (insertion Sort with mutable vectors)

I am writing an insertion sort in Haskell using mutable vectors. I can't figure out how to break out of a forM_ loop. I have commented where I need to do that.

mvInsertionSort :: Ord a => Mv.IOVector a -> IO (Mv.IOVector a)
mvInsertionSort mv = do
    forM_ [1 .. Mv.length mv - 1] $ \x -> do
        pivot <- Mv.read mv x
        forM_ [x-1 , x-2 .. 0] $ \y -> do
            currElem <- Mv.read mv y
            if pivot < currElem then Mv.write mv y pivot >> Mv.write mv (y+1) currElem
                else Mv.write mv (y+1) pivot -- Exit out of the second forM_ loop here
    return mv

Upvotes: 0

Views: 96

Answers (1)

Thomas M. DuBuisson
Thomas M. DuBuisson

Reputation: 64740

Well you can always use a continuation monad to provide extra return points:

import Control.Monad
import Control.Monad.Trans.Cont
import Data.Vector.Mutable as Mv

    mvInsertionSort :: Ord a => Mv.IOVector a -> IO (Mv.IOVector a)
    mvInsertionSort mv = do
     () <- evalContT $ callCC $ \exit ->
             forM_ [1 .. Mv.length mv - 1] $ \x ->
              do pivot <- Mv.read mv x
                 forM_ [x-1 , x-2 .. 0] $ \y ->
                  do currElem <- Mv.read mv y
                     if pivot < currElem
                         then do Mv.write mv y pivot
                                 Mv.write mv (y+1) currElem
                         else do Mv.write mv (y+1) pivot
                                 exit ()
     return mv

But I think most people just write custom recursive definitions instead.

Upvotes: 3

Related Questions