Channel Directions in Standard ML
(* When using channels as function parameters in Standard ML, we can use
ref types to simulate send-only or receive-only channels. This specificity
increases the type-safety of the program. *)
(* This `ping` function only accepts a channel for sending values. *)
fun ping (pings: string option ref, msg: string) =
pings := SOME msg
(* The `pong` function accepts one channel for receives (pings)
and a second for sends (pongs). *)
fun pong (pings: string option ref, pongs: string option ref) =
case !pings of
SOME msg => pongs := SOME msg
| NONE => ()
(* Main function to demonstrate the usage *)
fun main () =
let
val pings = ref NONE
val pongs = ref NONE
in
ping (pings, "passed message");
pong (pings, pongs);
case !pongs of
SOME msg => print (msg ^ "\n")
| NONE => print "No message received\n"
end
(* Run the main function *)
val _ = main ()
In Standard ML, we don’t have built-in channels like in some other languages. However, we can simulate similar behavior using reference types (ref
) and options. Here’s how the code works:
We define
ping
andpong
functions that operate onstring option ref
types. These act as our “channels”.The
ping
function takes a “send-only” channel (pings
) and a message. It updates the reference with the message.The
pong
function takes a “receive-only” channel (pings
) and a “send-only” channel (pongs
). It reads frompings
and writes topongs
.In the
main
function, we create two references to simulate channels, then callping
andpong
, and finally print the result.
To run this program, you would typically save it in a file (e.g., channel_directions.sml
) and then use an SML interpreter or compiler. For example, with Standard ML of New Jersey (SML/NJ):
$ sml channel_directions.sml
passed message
This example demonstrates how to simulate channel-like behavior in Standard ML, even though the language doesn’t have built-in support for channels. The use of reference types and options allows us to create a similar send/receive paradigm.