2016-08-01 56 views
0

我一直在嘗試在Prolog中編寫一個簡單的Web服務,並想知道如何處理可選參數。我認爲,與library(http/http_parameters)它可能是那樣簡單:在Prolog中處理可選的HTTP參數

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/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). 

辨例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]) :- 
     ... 

這似乎很確定我。