2015-05-17 23 views
3

由於我只找到關於這個錯誤的日文網頁,我想,讓我們記錄下來,問這裏,因爲我的日語有點生疏。多案例參數化活動模式返回錯誤FS0722只有返回一個結果的活動模式可能會接受參數

如果我有以下FSharp有源圖案(簡化的示例):

let (|InRange|OutOfRange|) from too = 
    function 
    | input when input >= from && input <= too -> InRange 
    | _ -> OutOfRange 

它完美地編譯和顯示其類型爲:

val (|InRange|OutOfRange|) : 
    from:'a -> too:'a -> _arg1:'a -> Choice<unit,unit> when 'a : comparison 

但是當我嘗試使用它,即,作爲如下,它拋出一個錯誤:

let test i = match i with 
      | InRange 10 20 -> "in range" 
      | _ -> "out of range" 

Throws: error FS0722: Only active patterns returning exactly one result may accept arguments

我可以通過將它變成兩個單例參數化活動模式來解決它,每個返回None/Some(x),但我仍然想知道爲什麼我不允許這樣做和/或是否有我可以使用的語法我不知道。我也想知道它爲什麼編譯,但我不能使用它?

回答

6

最簡單的解決辦法是重構這爲partial active pattern

let (|InRangeInclusive|_|) lo hi x = 
    if lo <= x && x <= hi then Some() else None 

然後你甚至可以將它們組合起來的東西是這樣的:

let test i = match i with 
     | InRangeInclusive 10 20 -> "in first range" 
     | InRangeInclusive 42 100 -> "in second range" 
     | _ -> "out of range" 

注意,我把我的自由給予模式一個更好的名字,因爲那些會使用你的代碼的人可能會對它的行爲感到困惑。

I'm still wondering why I am not allowed doing so?

Why can't non-partial active patterns be parameterized in F#?

+0

是的,這的確是做的(我在最後第簡要地提到)順理成章的事情。我主要對它編譯的事實感到驚訝,直到你實際使用這個模式。它編譯到和/或可能使用編譯的多案例活動模式,可能在模式匹配的上下文之外? – Abel

+0

PS:我之前沒有找到鏈接問題,因爲我使用錯誤代碼'FS0722'進行搜索,鏈接問題具有相同的錯誤描述,但代碼不同。 – Abel

+0

我沒有仔細檢查IL是如何生成的,但鏈接的答案似乎是合乎邏輯的:非部分活動模式函數只被調用一次,並且在那個時候沒有辦法綁定參數。 我已經編輯了鏈接Q,以便將來有人可以找到它。 – bytebuster

相關問題