在之前的一个问题中,我被告知如何重写我的计算表达式,因此它使用尾递归.我重写了我的代码,但仍然得到了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) 一些背景优先.我目前正在学习一些关于monadic解析器组合的东西.当我试图从本文中转移'chainl1'功能时(第16-17页),我提出了这个解决方案:
let chainl1 p op = parser {
let! x = p
let rec chainl1' (acc : 'a) : Parser<'a> =
let p' = parser {
let! f = op
let! y = p
return! chainl1' (f acc y)
}
p' <|> succeed acc
return! chainl1' x
}
Run Code Online (Sandbox Code Playgroud)
我用一些大输入测试了函数,得到了一个StackOverflowException.现在我想知道,是否可以重写一个递归函数,它使用一些计算表达式,因此它使用尾递归?
当我扩展计算表达式时,我看不出它通常是如何可能的.
let chainl1 p op =
let b = parser
b.Bind(p, (fun x ->
let rec chainl1' (acc : 'a) : Parser<'a> =
let p' =
let b = …Run Code Online (Sandbox Code Playgroud)