2010-10-28 85 views
6

是否可以部分應用bprintf等功能,並根據其初始用途防止其受到限制?保留部分應用功能通用

我想做到以下幾點:

let builder = new System.Text.StringBuilder() 
let append = Printf.bprintf builder 
append "%i" 10 
append "%s" string_value 

回答

8

可以增加明確格式參數

let builder = new System.Text.StringBuilder() 
let append format = Printf.bprintf builder format 
append "%i" 10 
append "%s" "1" 
+0

感謝。任何人都可以解釋爲什麼這個工程和部分應用程序不? – Daniel 2010-10-28 21:31:10

+10

因爲在.NET中,函數可以是通用的,而變量不能。 'let append format ='描述一個函數; 'let append ='描述一個變量。 – 2010-10-28 21:34:06

12

F#是造成這被稱爲值限制的方面。你可以看到,如果你只輸入兩個let聲明,以F#互動(這樣編譯器不會從第一次使用推斷出類型):

> let builder = new System.Text.StringBuilder() 
    let append = Printf.bprintf builder ;; 

錯誤FS0030:值限制。當'_a:> Printf.BuilderFormat <'_b> 'append'被推斷爲具有 泛型類型val append:('_a - >'_b)或者,如果您不打算爲 它是通用的,添加一個類型註釋。

有一個來自F#團隊的excellent article by Dmitry Lomov詳細解釋它。正如文章所建議的,一種解決方案是添加明確的類型參數聲明:

let builder = new System.Text.StringBuilder() 
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder 
append "%i" 10 
append "%s" "Hello" 

這將工作得很好。