2017-09-27 114 views
3

我期望它是一個接受兩個字符串並返回一個整數選項的函數。爲什麼這個f#代碼不能編譯?

let helper (f : string -> string -> bool * int) = f >> function 
    | (true, item) -> Some item 
    | (false, _) -> None 
+1

你會得到什麼錯誤? –

+0

(真,項目) 「這表達預計將有類型 '字符串 - > BOOL *詮釋' 但這裏有類型 'A * B' 」。 編譯器假定結果函數帶有一個參數。我想了解爲什麼做出這個決定。 – user540570

回答

1

f接受兩個參數。 >>只咖喱一個參數。你可以把它寫這種方式編譯:

let helper (f : string -> string -> bool * int) = 
     fun a -> f a >> function 
         | (true, item) -> Some item 
         | (false, _) -> None 

或者你也可以包括在函數簽名本身是第一個參數,像這樣:

let helper (f : string -> string -> bool * int) a = f a >> function 
    | (true, item) -> Some item 
    | (false, _) -> None 
3

這種情況很容易被解釋擴展代碼,所以功能傳遞/合成較少。

讓我們移除撰寫運營商>>和使用管道|>代替,加入一個明確aString參數:

let helper (f : string -> string -> bool * int) aString = 
    f aString |> function 
    | (true, item) -> Some item 
    | (false, _) -> None 

現在讓我們使用fun,而不是function具有明顯的參數x

let helper (f : string -> string -> bool * int) aString = 
    f aString 
    |> fun x -> 
     match x with 
     | (true, item) -> Some item 
     | (false, _) -> None 

現在讓我們通過內聯fun

let helper (f : string -> string -> bool * int) aString = 
    match (f aString : string -> bool * int) with 
    | (true, item) -> Some item 
    | (false, _) -> None 

此代碼等同於您開始使用的代碼。 f aStringf函數,只有一個字符串應用於它。由於咖喱,這種表達的類型是string -> bool * int。我在上面的代碼中添加了一個類型註釋來證明這一點。在產生bool * int的結果之前,需要提供另一個字符串。

+0

感謝您的解釋! 但爲什麼不編譯器來選擇下面的代碼是等同的: '讓助手(F:字符串 - >字符串 - > BOOL * INT)ASTRING bString = ˚FASTRING bString |>功能 | (true,item) - >一些項目 | (false,_) - > None' – user540570

+1

因爲它不相同! :)它不遵循語言的語法規則將它們視爲同一件事。 '>>'不能動態地計算出在靜態類型系統中傳遞多少個參數。爲了保持相同的結構,你可以定義運算符'let(>> +)f g a b = f a b |> g'並用它來代替。但是,請不要這樣做,因爲它會不必要地混淆。 – TheQuickBrownFox

+0

得到它終於) >>運算符與單個參數 定義這是我期待它的工作方式: '讓(>> +)fgxy = FXY |「G 讓助手(F: string - > string - > bool * int)= f >> +函數 | (true,item) - >一些項目 | (false,_) - > None' 謝謝! – user540570