相关疑难解决方法(0)

避免堆栈溢出(使用F#无限序列序列)

我有这个"学习代码",我为f#中的morris seq编写,它遇到堆栈溢出,我不知道如何避免."morris"返回无限序列的"看见和说出"序列(即{{1},{1,1},{2,1},{1,2,1,1},{1,1,1 ,2,2,1},{3,1,2,2,1,1},...}).

    let printList l =
        Seq.iter (fun n -> printf "%i" n) l
        printfn ""

    let rec morris s = 
        let next str = seq {
            let cnt = ref 1  // Stack overflow is below when enumerating
            for cur in [|0|] |> Seq.append str |> Seq.windowed 2 do
                if cur.[0] <> cur.[1] then
                    yield!( [!cnt ; cur.[0]] )
                    cnt := 0
                incr cnt
        }
        seq {
        yield s
        yield! morris (next s) // tail recursion, no stack …
Run Code Online (Sandbox Code Playgroud)

stack-overflow f# tail-recursion sequences

29
推荐指数
2
解决办法
2975
查看次数

递归序列会泄漏内存吗?

我喜欢递归地定义序列,如下所示:

let rec startFrom x =
    seq {
        yield x;
        yield! startFrom (x + 1)
    }
Run Code Online (Sandbox Code Playgroud)

我不确定这样的递归序列是否应该在实践中使用.的yield! 出现是尾递归,但我不知道100%的自正在从另一个IEnumerable的内部调用.从我的角度来看,代码在每次调用时都会创建一个IEnumerable实例而不关闭它,这实际上会使这个函数泄漏内存.

这个功能会泄漏内存吗?就此而言,它甚至是"尾递归"?

[编辑添加]:我正在摸着NProf寻找答案,但我认为在SO上获得关于递归序列实现的技术解释是有帮助的.

f# memory-leaks tail-recursion sequence

10
推荐指数
1
解决办法
1884
查看次数

递归计算表达式

在之前的一个问题中,我被告知如何重写我的计算表达式,因此它使用尾递归.我重写了我的代码,但仍然得到了StackOverflowException.为了找到问题,我使用状态monad编写了一些小代码(取自此博客条目):

type State<'a, 's> = State of ('s -> 'a * 's)

let runState (State s) initialState = s initialState

let getState = State (fun s -> (s,s))
let putState s = State (fun _ -> ((),s))

type StateBuilder() =
  member this.Return a = State (fun s -> (a, s))
  member this.Bind(m, k) = 
    State (fun s -> let (a,s') = runState m s in runState (k a) s')
  member this.ReturnFrom a = a
let state …
Run Code Online (Sandbox Code Playgroud)

stack-overflow f# tail-recursion computation-expression

6
推荐指数
1
解决办法
447
查看次数