2014-03-27 15 views
5

長話短說,我想出了這個有趣的功能設置,這需要一個功能,F:數k - >‘V,選定的值,K:’ ķ,所選擇的結果,ν:「v,使用˚F作爲新功能克的基礎:數k - >「v即確切相同˚F,除了它現在認爲,gk = vF# - 治療功能就像一張地圖

這裏是(很簡單)F#我爲了寫代碼,使其:

let set : ('k -> 'v) -> 'k -> 'v -> 'k -> 'v = 
    fun f k v x -> 
     if x = k then v else f x 

我的問題是:

,這種功能帶來什麼問題?

我能想象重複使用的功能,這樣

let kvs : (int * int) List = ... // A very long list of random int pairs. 
List.fold (fun f (k,v) -> set f k v) id kvs 

將開始建立對堆函數的長列表。這是值得關注的嗎?

有沒有更好的方法來做到這一點,而仍然保持類型?

我的意思是,我做的東西一樣構造一個類型爲第二保持原有的功能,˚F,地圖,鍵值對設置地圖,並首先檢查映射,函數,當使用鍵來獲取值時,這並不是我感興趣的地方 - 對於一個給定的函數,我有一個函數可以修改給定值的單個結果。

回答

5

潛在的問題:

  1. set修飾的功能,如果你重寫相同值的兩倍泄漏空間:

    let huge_object = ... 
    let small_object = ... 
    
    let f0 = set f 0 huge_object 
    let f1 = set f0 0 small_object 
    

    即使它永遠是f1輸出,huge_object不能垃圾收集到f1可以:huge_object被引用f0,而這又被f1引用。

  2. set修改後的函數在應用於它的set操作的數量上具有線性開銷。

我不知道這些都是實際問題爲目標應用程序。

如果你想set確切類型('k -> 'v) -> 'k -> 'v -> 'k -> 'v然後我沒有看到更好的方式(*)。顯而易見的想法是對已經修改過的函數進行「修改表」,然後讓set在此表中查找給定的f。但函數類型不允許進行相等性檢查,所以您不能將f與修改表中已知的函數集進行比較。

(*)反映不足。

+0

你提到反思。你可以多談一下如何使用它? 另外,如果類型**'k **是一個簡單的區分聯合? – phaz

+0

這並沒有什麼區別''k'是一些已知類型't'。然後你會考慮函數'(t - >'v)',但是_no_函數類型是平等的,所以也不是這個。 (這是計算機科學領域的一個着名結果,一般不可能確定兩個函數是否相等,即對於相同的輸入產生相同的輸出。) –

+0

Wrt。反思,我想你可以使用反射來獲得對函數''k - >'v'的運行時表示的引用。你可以比較平等,所以放在地圖上。 –