Channels in Haskell

Channels in Haskell are typically implemented using the Control.Concurrent.Chan module. These channels allow communication between different threads. You can send values into channels from one thread and receive those values in another thread.

import Control.Concurrent
import Control.Concurrent.Chan

main :: IO ()
main = do
    -- Create a new channel
    messages <- newChan

    -- Send a value into the channel from a new thread
    forkIO $ writeChan messages "ping"

    -- Receive the value from the channel and print it
    msg <- readChan messages
    putStrLn msg

Let’s break down this example:

  1. We import the necessary modules: Control.Concurrent for thread management and Control.Concurrent.Chan for channel operations.

  2. We create a new channel using newChan. This channel can carry String values.

  3. We use forkIO to create a new thread that sends the string "ping" into the messages channel using writeChan.

  4. In the main thread, we receive the value from the messages channel using readChan and store it in msg.

  5. Finally, we print the received message.

When we run the program, the "ping" message is successfully passed from one thread to another via our channel.

$ runhaskell channels.hs
ping

By default, readChan blocks until a value is available, and writeChan blocks until the value is read. This property allows us to synchronize the threads without using any additional mechanisms.

In Haskell, channels provide a way to communicate between threads, similar to how they’re used in concurrent programming in other languages. They’re particularly useful for implementing producer-consumer patterns and other concurrent algorithms.