管道

我们现在将再次改变我们对协程建模的方式,使用记录是参数而不是元组。

// writer fibre
proc writer (io: (out: %>int)) ()
{
  for i in 1..10 do
    println$ "Sending " + i.str;
    write (io.out,i);
  done
}

// reader fibre
proc reader (io: (inp: %<int)) ()
{
  while true do
    var x = read inp;
    println$ "Read " + x.str;
  done
}

proc doubler (io: (inp: %<int, out: %>int)) ()
{
  while true do
    var x = read io.inp;
    write (io.out, 2 * x);
  done
}

proc start_network () {
  // schannels for communication
  var inp1, out1 = mk_ioschannel_pair[int]();
  var inp2, out2 = mk_ioschannel_pair[int]();
  spawn_fibre$ writer (out=out1);
  spawn_fibre$ doubler (inp=inp1,out=out2);
  spawn_fibre reader (inp=inp2);
}

start_network;

这里协程使用单个记录作为参数,记录的每个字段都是一个通道。这样做的好处是,由于参数是命名的,因此更容易正确传递参数,而不必按特定顺序排列。

使用这个协议,我们也可以重写 start_network

proc start_network () {
   run$ writer |-> doubler |-> reader;
}

作家也叫作家 来源 . 读卡器也称为读卡器 sink . 一个循环,它先读取值,然后对该值执行某些操作,然后写入,称为 传感器 .

如果你有一个源连接到一系列的传感器,并以一个接收器结束,那就是所谓的 封闭式管道 . 左关联中缀管道操作符 |-> 可用于将协程连接到管道中。合成的结果本身就是一个协同程序。

并非所有的协同路由网络都是管道,但是它们是非常常见的,既作为整个网络,也作为更复杂网络的子部分。

在函数式编程中,管道与单子是双重的。。但它们更容易使用,效率更高。