2

我现在正在大学里自学课程,并注意到我咬得比我能咀嚼的多一点。该课程是关于 Oz 编程语言的,我正在阅读一本关于它的电子书以尝试更好地了解它,并且我正在尝试解决一些练习来测试我的理解。我很卡在某个练习上,我不太知道如何解决它。问题是:

实施端口。在第 5 章中我们介绍了端口的概念,它是一个简单的通信通道。端口有操作 {NewPort SP},它返回一个带有流 S 的端口 P,和 {Send PX},它在端口 P 上发送消息 X。从这些操作中,很明显端口是一个有状态的非捆绑 ADT。在本练习中,使用第 6.4 节的技术根据单元实现端口。

关键词是 stateful unbundled 和 cell。我尝试通过以下方法使用单元来实现端口的行为:

declare
MyPort
MyStream
proc {NewPortEx ?S ?P}
   P = {NewCell nil}
   S = !!P  %read only view on the cell
end
proc {SendEx P X}
   P:=X|@P  %extend the cell's content, a list, with X
end
in
{NewPortEx MyStream MyPort}
{Browse @MyStream}
{SendEx MyPort c}
{Browse @MyStream}

我的最后一步是添加一个包装器/解包器对以确保 ADT 安全,但首先我希望该功能能够正常工作。这似乎是正确的行为,但这不是我想要的。我希望能够在{Browse MyStream}没有 , 的情况下调用@一次。我希望浏览器会显示一些内容,firstSent|secondSent|_<future>而不是<Cell>按预期显示,我需要Browse在每个 之后调用它Send,并且输出显示为 list: [firstSent secondSent]

如果我从我读过的理论中没记错的话,这与急切与懒惰的评估有关,分别导致(有限)列表与(无限)流。

我觉得我做得不太对,而且我对函数式语言没有任何经验,谁能帮我做一个用单元实现的端口的例子?(基本上你自己实现现有的NewPortand Send

提前致谢

4

1 回答 1

1

流只是一个带有未绑定尾部的列表。例如,最初列表只是一个未绑定的变量_。每当发送一个元素时,尾部都会绑定到一个新对,例如:

(1) Initially:          S = _
(2) Send 1 to the port: S = 1|_
(3) Send 2 to the port: S = 1|2|_
etc.

除非您关闭端口,否则尾部始终保持未绑定。

现在,您将单元格用作指向列表末尾的指针。最初,该单元格仅指向 S。然后,SendEx 操作包括以下步骤:

(1) Read the current tail from the cell.
(2) Declare a new unbound variable that will serve as the new tail.
(3) Unify: current tail = X | new tail
(4) Store the new tail in the cell.

希望这可以帮助。

于 2012-04-14T22:57:21.647 回答