芯片

好吧,现在我们要再次更改符号!开始吧:

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

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

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

run$ writer |-> doubler |-> reader;

这些芯片与我们之前的读写器和倍增程序完全相同,我们只是在语法上加了些糖,使它们看起来像集成电路规范。

一个芯片可以有多个连接器,连接器名称只是参数名称。每个连接器可以有多个管脚,管脚名称只是记录字段名。这个语法有点冗长,但是它更容易阅读,并且使过程的目的和预期用途变得清晰。

标准芯片

这个库包含许多标准芯片。

写入块

故意阻止一个作家。当写入程序写入连接到该设备的通道时,不会发生任何操作,因此写操作会阻塞。

chip writeblock[T]
  connector io
    pin inp : %<T
{
}

读取块

故意让读者忍饥挨饿。当读卡器试图从连接到该设备的通道中读取数据时,什么都不会发生,因此读卡器会饿死。

chip readblock[T]
  connector io
    pin out: %>T
{
}

通用水槽

永远读取输入,但忽略它。

chip sink[T]
  connector io
    pin inp : %<T
{
  while true do
    var x = read (io.inp);
    C_hack::ignore (x);
  done
}

恒定来源

写入固定值 a 永远。

chip source[T] (a:T)
  connector io
    pin out: %>T
{
  while true do
    write (io.out, a);
  done
}

一次性震源

写入固定值 a 然后退出。

chip value[T] (a:T)
  connector io
    pin out: %>T
{
  write (io.out, a);
}

发电机电源

调用生成器以获取值,然后重复写入该值。

chip generator[T] (g: 1->T)
  connector io
    pin out: %>T
  {
    repeat perform write (io.out, g());
  }

来自迭代器的源

该芯片从迭代器读取值并将其流式传输到输出,直到迭代器返回None。这是一个手动优化版本的低效 for v in x perform write(io.out,v); .

chip iterate[T] (g: 1->opt[T])
  connector io
    pin out: %>T
  {
    again:>
      var x = g();
      match x with
      | Some v =>
        write (io.out, v);
        goto again;
      | None => ;
      endmatch;
  }

来源列表

专门用于列表的列表迭代器。当列表中的所有值都已写出时,它将返回。

chip source_from_list[T] (a:list[T])
  connector io
    pin out: %>T
{
  for y in a perform write (io.out,y);
}

从列表绑定源

此例程从列表生成一个选项流 a . 每个值写为 Some v 直到名单用尽,才有无限的人流 None[T] 是书面的。

因为这条河是有边界的 符合逻辑的 流的内容以None结尾;也就是说,选项类型被用作载波类型。

chip bound_source_from_list[T] (a:list[T])
  connector io
    pin out: %>opt[T]
{
  for y in a perform write (io.out,Some y);
  while true perform write (io.out,None[T]);
}

功能适配器

最有用的芯片之一,函数适配器读取一个值流,应用函数 f 把它们写出来。它是函数式编程的对偶 map 超过列表。

chip function[D,C] (f:D->C)
  connector io
    pin inp: %<D
    pin out: %>C
{
  while true do
    var x = read io.inp;
    var y = f x;
    write (io.out, y);
  done
}

程序适配器

将过程转换为接收器。读取值并调用过程 p 在每个人身上。

chip procedure[D] (p:D->0)
  connector io
    pin inp: %<D
{
  while true do
    var x = read io.inp;
    p x;
  done
}

滤波器

读取并写出满足谓词的值 f . 双重功能编程过滤列表。

chip filter[D,C] (f:D->opt[C])
  connector io
    pin inp: %<D
    pin out: %>C
{
  while true do
    var x = read io.inp;
    match f x with
    | Some y => write (io.out, y);
    | None => ;
    endmatch;
  done
}

过滤和映射

应用谓词 c ,并编写 f 去满足它的价值。

chip filter[D,C] (c:D->bool) (f:D->C)
  connector io
    pin inp: %<D
    pin out: %>C
{
  while true do
    var x = read io.inp;
    if c x do
       write (io.out, f x);
    done
  done
}

汇到列表

这个芯片是一个接收器,它读取值并将它们推送到由指针标识的扩展列表中。必须在生成协同进程之前初始化该列表。

chip sink_to_list[T] (p: &list[T])
  connector io
    pin inp : %<T
{
  while true do
    var x = read (io.inp);
    p <- Cons (x,*p);
  done
}

汇到唯一列表

等同于 sink_to_list 但只有当值不存在时才会将其推送到列表中。

chip sink_to_unique_list[T with Eq[T]] (p: &list[T])
  connector io
    pin inp : %<T
{
  while true do
    var x = read (io.inp);
    if not (x in *p) perform
      p <- Cons (x,*p)
    ;
  done
}

缓冲区

也许最重要和最有用的芯片,它只是将输入复制到输出。

chip buffer [T]
  connector io
    pin inp: %<T
    pin out: %>T
{
  while true do
    var x = read io.inp;
    write (io.out, x);
  done
}