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 resultWhen 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 messageThis 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.