【问题标题】:Passing a GOAL as argument ? Plus variable number of arguments?将目标作为参数传递?加上可变数量的参数?
【发布时间】:2021-04-08 12:10:09
【问题描述】:

通常试图弄清楚如何将目标/函数作为参数传递。 /类似于 Ruby BLOCK 的概念/

在这种特定情况下,尝试使用可变数量的参数,但 call/2 只允许固定

split(Str, Lst) :- split_string(Str, " ", "", Lst).
split(Str, Separator, Lst) :- split_string(Str, Separator, "", Lst).
split(Str, Separator, Pad, Lst) :- split_string(Str, Separator, Pad, Lst).
read_line(Stream,Process,Args) :- read_line_to_string(Stream,Str), call(Process,Str,Args). 

第一种情况有效,即 split(Str,Lst),但调用不允许可变数量的参数。

?- open('facts.txt',read,Str), read_line(Str,split,P), close(Str).
Str = <stream>(0x564fc8884290),
P = ["example", "of.fact", "\"man(socrates).\""].

apply/2 似乎是我需要的,但被贬低了

请记住,我正在考虑除了 split() 之外还有其他过程/功能

我该怎么做?

PS> 如果我有更奇怪的情况怎么办,其中第一个和最后一个参数是预先确定的,我想在两者之间填充参数。 最初我尝试过:

  read_line(Stream,Args?,Lst) :- read_line_to_string(Stream,Str), split(Str, ..., Lst). 

如您所见,两者之间需要填充 args。

【问题讨论】:

    标签: prolog arguments parameter-passing variadic-functions


    【解决方案1】:

    我不知道为什么 apply/2 被标记为已弃用(至少在 SWI-Prolog 文档中)——无论如何,您可以使用 call/2=../2 轻松实现它。

    另一种选择是像这样定义 read_line:

    read_line(Stream,Process,Arg1)           :- read_line_to_string(Stream,Str), call(Process,Str,Arg1). 
    read_line(Stream,Process,Arg1,Arg2)      :- read_line_to_string(Stream,Str), call(Process,Str,Arg1,Arg2).
    read_line(Stream,Process,Arg1,Arg2,Arg3) :- read_line_to_string(Stream,Str), call(Process,Str,Arg1,Arg2,Arg3).
    % etc., for as many args as  you think are reasonable.  
    

    【讨论】:

    • apply/2call/2..8 相比具有更高的开销(列表、args 因此在全局堆栈上传递)。
    • 是的,但是 if 参数已经在列表中,那么 apply/2 是有意义的。在此处给出的示例中, apply/2 没有意义,因为可以显式列出各种选项。
    • 当参数在列表中时,没有输入 - 甚至没有交叉引用。
    猜你喜欢
    • 2015-09-22
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    相关资源
    最近更新 更多