2016-08-01 4 views
0

Я пытался написать простой веб-сервис в Prolog и задавался вопросом, как я могу обрабатывать необязательные параметры. Я думал, что с library(http/http_parameters) это может быть столь же простым, как:Обработка дополнительных параметров HTTP в Prolog

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

Резюме

Есть по крайней мере два выхода:

  1. Вы может объединить optional/1 с default/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). 

и различать случаи с if_3:

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

Главный недостаток: Для того, чтобы действительно отличить случаев по шаблон соответствия, вам придется преобразовать это в чистый представление. Без этого вы также рискуете, что один из атрибутов законно перекрывается со значением, которое вы используете, чтобы означать «не  ». Одним из подходящего представления может выглядеть следующим образом:

  • none для "не указаны"
  • atom(A) для атома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]) :- 
     ... 

Это кажется вполне нормально для меня.

Смежные вопросы