【发布时间】:2016-02-01 21:08:17
【问题描述】:
This other question 问的几乎一样,但不完全一样。相反,我如何要求一个目标确定地成功(恰好一次)并且不留下任何选择点?
这在用作命令行工具的 Prolog 程序的上下文中特别有用:可能从标准输入读取、获取参数并写入标准输出。在这样的程序中,做完工作留下一个选择点,总是程序员的错误。
SWI-Prolog 提供deterministic/1,所以可以这样写:
( deterministic(true)
-> true
; fail
)
提出了另一种更便携的方法来实现同样的目的:
is_det(Goal, IsDet) :-
setup_call_cleanup(true, Goal, Det=true),
( Det == true
-> IsDet = true
; !,
IsDet = false
).
不过,发生这种情况时抛出错误似乎很有用,但我不知道这个错误会是什么。我非常仔细地查看了ISO error terms,找不到可以明显描述这种情况的错误。
抛出错误确实更好,还是我应该失败?如果首选抛出错误,那么该错误会是什么?
编辑:我不知道该怎么做,因为特别是当涉及到副作用时,比如向标准输出写入一些东西,让副作用发生感觉非常错误,然后 em>失败。几乎有必要宁愿抛出一个异常。这还可以确定剩余的选择点是无害的(如果不需要的话)并捕获异常,然后写入标准错误或返回不同的退出代码。
但我真的不知道什么能正确描述异常,所以我不知道要抛出什么术语。
【问题讨论】:
-
“发生副作用并然后失败感觉非常错误”:我已经为这句话投了赞成票!
-
@mat:这就是 haskell 教的,安排你的副作用。如果您需要副作用,请将它们与您的推理分开。
-
@MiloslavRaus 将副作用分开是非常好的,但您最终必须承诺它们。永远延迟像输出这样的副作用是不切实际的。选择点确实有自己的方式潜入您的代码,尤其是在使用 DCG 时。 (只要您注意到它,就有许多描述良好的技术可以消除不需要的非确定性。)
-
您需要一个新的错误术语,不知道如何调用它。 Related:
call_semidet/1. -
@Miloslav Raus:很高兴看到其他语言现在也提倡这种分离。
标签: exception error-handling prolog swi-prolog