Something went wrong. Try again.
Mutable List builder in the ST Monad
Something went wrong. Try again.
1.5 kB · 70 lines
Haskell
at master
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071-- | Traversing IO lists.---- Code from this module is derived from [Twan van Laarhoven](https://www.twanvl.nl/blog/haskell/unsafe-sequence).---- These operations are tail recursive, while building lists by appending-- to its tail mutably.module Data.Traversable.IO ( sequenceIO , traverseIO , unfoldIO) where
import Data.ListBuilder.Unsafe
import Prelude hiding (length)
-- | Traverse implemented in terms of unsafeSetField.---- This operation is tail recursive.traverseIO :: (a -> IO b) -> [a] -> IO [b]traverseIO _ [] = return []traverseIO f (mx0:xs0) = do x0 <- f mx0 let front = [x0] go front xs0 return front where go _ [] = return () go back (mx:xs) = do x <- f mx let back' = [x] unsafeSetField 1 back back' go back' xs{-# INLINEABLE traverseIO #-}
-- | Sequence implemented in terms of unsafeSetField---- This operation is tail recursive.sequenceIO :: [IO a] -> IO [a]sequenceIO = traverseIO id{-# INLINE sequenceIO #-}
-- | Unfold a list from an IO action returning a 'Maybe' value.-- As long as the function returns `Just`, its value will-- be appended to the list.unfoldIO :: IO (Maybe a) -> IO [a]unfoldIO p = do x <- p case x of Nothing -> return [] Just a -> do let front = [a] go front return front where go back = do x <- p case x of Nothing -> return () Just a -> do let back' = [a] unsafeSetField 1 back back' go back'{-# INLINEABLE unfoldIO #-}