{-| Module : MySum Description : A module to compute the sum of a list of numbers. Copyright : © Frank Jung, 2025 License : GPL-3 This is a simple example of using the 'ST' Monad for stateful summation of a list. The 'ST' monad in Haskell allows you to perform mutable (stateful) computations in a safe, local way. It stands for "State Thread" and is defined in Control.Monad.ST ('ST'). == Key Points [Local Mutability] You can create and modify mutable variables ('STRef's) inside the 'ST' monad. [Safety] Changes made in the 'ST' monad are not visible outside; the mutation is encapsulated. [Pure Interface] When you run an 'ST' computation (using 'runST'), you get a pure result, and the mutable state cannot escape. == Example usage Computes the sum of a list using the 'mySum' function: @ let total = mySum [1, 2, 3, 4, 5] @ -} module MySum ( mySum ) where import Control.Monad.ST import Data.STRef -- | Computes the sum of a list of integers using the ST monad. sumSt :: [Int] -- ^ The list of integers to sum -> STRef s Int -- ^ A mutable reference to accumulate the sum -> ST s Int -- ^ The stateful computation that returns the sum sumSt :: forall s. [Int] -> STRef s Int -> ST s Int sumSt [] STRef s Int _ = Int -> ST s Int forall a. a -> ST s a forall (m :: * -> *) a. Monad m => a -> m a return Int 0 -- Base case: empty list returns 0 sumSt (Int x:[Int] xs) STRef s Int accumRef = do Int accum <- STRef s Int -> ST s Int forall s a. STRef s a -> ST s a readSTRef STRef s Int accumRef -- Read the current value of the accumulator STRef s Int -> Int -> ST s () forall s a. STRef s a -> a -> ST s () writeSTRef STRef s Int accumRef (Int accum Int -> Int -> Int forall a. Num a => a -> a -> a + Int x) -- Update the accumulator with the new value [Int] -> STRef s Int -> ST s Int forall s. [Int] -> STRef s Int -> ST s Int sumSt [Int] xs STRef s Int accumRef -- Recursively for the remaining elements -- | Computes the sum of a list of integers in a stateful manner. mySum :: [Int] -> Int mySum :: [Int] -> Int mySum [Int] xs = (forall s. ST s Int) -> Int forall a. (forall s. ST s a) -> a runST ((forall s. ST s Int) -> Int) -> (forall s. ST s Int) -> Int forall a b. (a -> b) -> a -> b $ do STRef s Int accumRef <- Int -> ST s (STRef s Int) forall a s. a -> ST s (STRef s a) newSTRef Int 0 -- Create a new STRef to hold the accumulator Int _ <- [Int] -> STRef s Int -> ST s Int forall s. [Int] -> STRef s Int -> ST s Int sumSt [Int] xs STRef s Int accumRef -- Compute the sum using the ST monad STRef s Int -> ST s Int forall s a. STRef s a -> ST s a readSTRef STRef s Int accumRef -- Read the final sum from the STRef