Reputation: 419
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
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