2011-04-02 185 views
1

我測試以下代碼遞歸地填充字典。然而,類型推斷似乎不能識別字典類型。我試過使用類型註釋,但似乎沒有幫助。遞歸填充字典?

在遞歸例程中是否對字典的使用有一些限制。我是否需要讓字典可變,因爲我希望在迭代過程中對其進行更改。

open System 
open System.Collections.Generic 

////dictionary recursion test 

let pop_dict tlist = 
    // let rec inner tlist acc ddict:Dictionary<string,int> = 
    let rec inner tlist acc ddict = 
     match tlist with 
      | [] -> ddict.Add ("dummykey", acc)        
      | x::xs -> inner xs (x::acc) ddict 
    let ddict = Dictionary<string,int>() 
    inner tlist [] ddict 


// Main Entry Point 
let main() = 

    let tlist = [1;2;3;4] 
    let d = pop_dict tlist 

main() 
+0

你想要一個帶有一個鍵(「dummykey」)的可變字典,它包含你傳入的列表? let dic = Dictionary (); dic.add(「dummykey」,[1,2,3,4]) – 2011-04-02 22:08:18

回答

4

首先,你的類型不匹配。

您正試圖將int list(這是什麼acc)添加到應該包含int s的字典中。

但是,除此之外,編譯器無法推斷出ddict類型的原因是。請記住,當類型檢查器確定函數的類型時,它不會查看稍後調用的內容。它只有提供以下信息:

let rec inner tlist acc ddict = 
    match tlist with 
     | [] -> ddict.Add ("dummykey", acc)        
     | x::xs -> inner xs (x::acc) ddict 

這意味着,唯一的信息,它知道ddict當它編譯功能,就是它有一個名爲Addstring * 'a list -> ?的方法。

要修復它,改變

let rec inner tlist acc ddict = 

let rec inner tlist acc (ddict:Dictionary<string,int>) = 

你仍然有在字典中的不匹配類型的麻煩,然而,你可能希望它是Dictionary<string, int list>,如果你計劃在其中存儲int list

+0

好的解釋 - 獲取/檢查類型檢查規則很明確可能是學習F#中最棘手的部分 - 但它確實關注頭腦和(希望)提高我們的編碼技能。 – BrendanC 2011-04-02 13:14:02

1

是你想要的嗎?

let pop_dict tlist = 
    let rec inner tlist acc (ddict:Dictionary<string,int list>) = 
     match tlist with 
      | [] -> ddict.Add ("dummykey", acc)        
      | x::xs -> inner xs (x::acc) ddict 
    let ddict = Dictionary<string,int list>() 
    inner tlist [] ddict 


// Main Entry Point 
let main() = 

    let tlist = [1;2;3;4] 
    let d = pop_dict tlist 
    ()