2014-12-06 52 views
3

我目前正在嘗試使用Petricek和Skeet(2010)的實際函數編程一書學習f#,但在使用延續避免堆棧溢出時遇到了問題。在Visual Studio中使用延續啓動函數

我一直遇到的問題是使用continuations的代碼在f#interactive中啓動時工作正常,但在將代碼放入program.fs文件時仍然會導致堆棧溢出,然後通過Visual中的調試器啓動它工作室。

我不清楚爲什麼會發生這種情況,如果有人能給我一個解釋爲什麼會發生這種情況,我會非常感激。

如果Visual Studio中的版本是相關的,我使用: 的Visual Studio 2012最終版本 更新11.0.61030.00 4

使用.NET Framework是: 版本。 4.5.51641

中,是造成這一問題的書提供的代碼介紹如下:

open System 
let rand = new Random() 

//A tree is either a leaf with a value or a node that contains two children 
type IntTree = 
    | Leaf of int 
    | Node of IntTree * IntTree 

//A list of that will decide all leaf values 
let numbers2 = List.init 1000000 (fun _ -> rand.Next(-50,51)) 

///Creates an imbalanced tree with 1000001 leafs. 
let imbalancedTree2 = 
    numbers2 |> List.fold (fun currentTree num -> 
     Node(Leaf(num), currentTree)) (Leaf(0)) 

//Sums all leafs in a tree by continuation and will execute the inserted function with the total  
//sum as argument once all values have been summed. 
let rec sumTreeCont tree cont = 
    match tree with 
    | Leaf(num) -> cont(num) 
    | Node(left, right) -> 
     sumTreeCont left (fun leftSum -> 
      sumTreeCont right (fun rightSum -> 
       cont(leftSum + rightSum))) 

//Sums the imbalanced tree using the sumTreeCont function 
let sumOfTree = sumTreeCont imbalancedTree2 (fun x -> x) 

提前感謝! // Tigerstrom

回答

3

如果您在調試模式下運行程序,則默認的Visual Studio項目設置會禁用尾部調用。主要原因在於,在啓用尾部調用的情況下,您不會在調用堆棧中獲得非常有用的信息(這會使調試更加困難)。

要解決這個問題,您可以轉到您的項目選項並在「生成」頁面上選中「生成尾部調用」。在發佈模式下,這是默認啓用的。

+0

非常感謝你,解決了這個問題! 另外我想感謝你一本好書。這是非常有教育意義的,包含了很棒的內容! – Tigerstrom 2014-12-06 17:42:27

+0

謝謝,我很高興你喜歡這本書:-) – 2014-12-06 22:22:09