在 Prolog 中处理可选的 HTTP 参数

Handling optional HTTP parameters in Prolog

我一直在尝试在 Prolog 中编写一个简单的 Web 服务,并且想知道如何处理可选参数。我认为使用 library(http/http_parameters) 可能就这么简单:

my_request_handler(Request) :-
    http_parameters(Request, [ param_1(Param1, []), param_2(Param2, []) ]),
    ... ### handle both parameters

my_request_handler(Request) :-
    http_parameters(Request, [ param_1(Param1, []) ]),
    ... ### handle only param_1

因此,如果未提供 param_2,引擎将回溯到第二条规则。但在 SWI-Prolog http_parameters 中,如果参数与规范不匹配,则会引发异常,因此代码会在第一条规则上中断,而不是尝试评估第二条规则。

不幸的是,将 optional(true) 添加到 param_2 规范使其不受约束并迫使我使用这样的条件检查:

my_request_handler(Request) :-
    http_parameters(Request, [ param_1(Param1, []), param_2(Param2, [optional(true)]) ]),
    (error:text(Param2) ->
       ... ### handle both parameters
    ;
       ... ### handle only param_1
    ).

这是最好的做事方式还是我遗漏了什么?我想,如果有多个参数是可选的,条件语句会变得更丑陋...

干杯,

总结

至少有两条出路:

  1. 您可以将 optional/1default/1 组合,并指定一个不会出现的值。

  2. 可以指定list/1得到一个列表,使用模式匹配区分大小写

详情见下文。

使用default/1

例如,要实现选项 1,您可以这样写:

my_request_handler(Request) :-
        http_parameters(Request, [ param_1(Param1, []),
                                   param_2(Param2, [optional(true),
                                                    default(none)])
                                 ]),
        handle_parameters_(Param1, Param2).

区分大小写:

handle_parameters_(Param1, Param2) :-
        if_(Param2 = none,
            Then,
            Else).

主要缺点:要通过 模式匹配 真正区分大小写,您必须将其转换为 clean 表示。否则,您还会冒其中一个属性与您用来表示 "not specified" 的值合法重叠的风险。一种合适的表示形式可能如下所示:

  • none 对于 "not specified"
  • atom(A)atom A.

但是,此转换再次需要您手动实现区分,例如使用您发布的示例中的 var/1

使用list/1

选项 (2) 不太容易出错,尽管稍微间接一些。

你可以这样应用:

my_request_handler(Request) :-
        http_parameters(Request, [ param_1(Param1, []),
                                   param_2(Param2, [list(atom)])
                                 ]),
        handle_parameters_(Param1, Param2).

然后,你可以通过模式匹配来区分大小写:

handle_parameters_(Param1, []) :-
        ...
handle_parameters_(Param1, [Param2]) :-
        ...

我觉得这还不错。