GHC.Conc vs stm

Hi,

I’m reading the book “Practical Web Development with Haskell”, published in 2018.

In chapter 3, we’re looking at the stm library. But I notice similar functions already exist in the standard prelude.

module Main (main) where

import GHC.Conc (
    atomically,
    newTVarIO,
    readTVar,
    readTVarIO,
    writeTVar,
 )

asyncOperation :: Int -> IO Int
asyncOperation v = do
    tvar <- newTVarIO v
    let add1 = readTVar tvar >>= \val -> writeTVar tvar (val + 1)
    let add1Actions = replicate 100 add1
    mapM_ atomically add1Actions
    readTVarIO tvar

main :: IO ()
main = do
    putStrLn "First operation"
    n1 <- asyncOperation 0
    putStrLn ("Result 1: " <> show n1)

    putStrLn "---"

    putStrLn "Second operation"
    n2 <- asyncOperation (n1 + 1)
    putStrLn ("Result 2: " <> show n2)

I have doubts about this line:

mapM_ atomically add1Actions

The book uses the function mapConcurrently which seems to come from the async package.

So my question is: has there been any changes into the base package since 2018, making the use of these 2 libraries obsolete?

In not, what are the limitations of the functions provided by base?

Modules starting with GHC. are often unstable and contain primitives. They are usually not covered by any versioning policy, so they can change with every new GHC release. Libraries like stm use primitives from those modules in a stable API and often extend them with derived functions like modifyTVar' (and much more).

7 Likes

That explains my confusion, many thanks!

and to answer the 2nd half
of your question: by all means keep using stm and async, as they are great

5 Likes