Channel Directions in PureScript

PureScript doesn’t have built-in channels like Go, but we can simulate similar behavior using the Effect monad and Refs. Here’s an equivalent implementation:

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Effect.Ref as Ref

-- This `ping` function only accepts a function for sending
-- values. It would be a type error to try to receive using this function.
ping :: (String -> Effect Unit) -> String -> Effect Unit
ping send msg = send msg

-- The `pong` function accepts one function for receives
-- and a second for sends.
pong :: Effect String -> (String -> Effect Unit) -> Effect Unit
pong receive send = do
  msg <- receive
  send msg

main :: Effect Unit
main = do
  pings <- Ref.new ""
  pongs <- Ref.new ""
  
  let sendPing = Ref.write pings
      receivePing = Ref.read pings
      sendPong = Ref.write pongs
      receivePong = Ref.read pongs

  ping sendPing "passed message"
  pong receivePing sendPong
  result <- receivePong
  log result

When using functions as parameters in PureScript, you can specify if a function is meant to only send or receive values. This specificity increases the type-safety of the program.

The ping function only accepts a function for sending values. It would be a type error to try to receive using this function.

The pong function accepts one function for receives and a second for sends.

In the main function, we create two Refs to simulate channels. We then define send and receive functions for each “channel” using Ref.write and Ref.read respectively.

To run this program, you would typically compile it with the PureScript compiler and then run it with Node.js:

$ spago build
$ node -e "require('./output/Main').main()"
passed message

This example demonstrates how to implement unidirectional communication patterns in PureScript, similar to channel directions in other languages. While PureScript doesn’t have built-in channels, we can achieve similar functionality using its powerful type system and effect handling capabilities.