Range Over Channels in Idris

In a previous example, we saw how for loops provide iteration over basic data structures. In Idris, we can use similar constructs to iterate over values received from a channel-like structure.

import System.Concurrency

main : IO ()
main = do
  -- We'll simulate a channel with a MVar containing a list of strings
  queue <- newEmptyMVar
  
  -- Put two values in the queue
  putMVar queue ["one", "two"]
  
  -- This loop iterates over each element received from the queue
  -- We use takeMVar to get the list and then map over it
  queueContents <- takeMVar queue
  traverse_ putStrLn queueContents

To run the program:

$ idris range-over-channels.idr -o range-over-channels
$ ./range-over-channels
one
two

This example demonstrates how to simulate channel-like behavior in Idris using MVars. While Idris doesn’t have built-in channels like some other languages, we can achieve similar functionality using its concurrency primitives.

In this case, we’re using an MVar to hold a list of strings, which simulates a buffered channel. We put two values into the MVar, then take the entire list out and iterate over it.

The traverse_ function is used to apply putStrLn to each element of the list, printing each value on a new line. This is similar to ranging over a channel in other languages.

Note that in Idris, we don’t need to explicitly close the MVar as we would with channels in some other languages. The garbage collector will handle cleanup when the MVar is no longer in use.

This approach doesn’t provide the exact same semantics as channels in some other languages, particularly for concurrent scenarios, but it demonstrates a way to achieve similar behavior in Idris.