为什么在此CPS解析器示例中未定义curried参数?

时间:2016-08-13 08:14:14

标签: f# continuations

代码:

type Result = string option
type Parser<'a> = string -> int -> ('a -> Result) -> ('a -> Result) -> Result
let win r = Some <| "Correct: " + r
let lose _ = None

let parse_a: Parser<char> = fun text i win_cps lose_cps ->
    let x = text.[i]
    if x = 'a' then win_cps x else lose_cps x

let parse_many: Parser<char> -> Parser<char list> = fun p text i win_cps lose_cps ->
    let rec loop: char list -> Parser<char list> = fun l text i _ _ ->
        let win = fun (l: char list) (r: char) -> loop (r:l) text i win_cps lose_cps
        let lose = fun (l: char list) (r: char) -> win_cps (r:l)
        p text (i+1) (win l) (lose l)
    loop [] text (i-1) win_cps lose_cps

parse_many parse_a "aaabc" 0 (fun r -> win (r |> System.String.Concat)) lose

错误:cps_parser_v0.fsx(12,59): error FS0039: The type 'l' is not defined

我想在Haskell中创建一个功能纯粹的CPS解析器,并且首先在F#中进行实验。如果我真的想在F#中这样做,我会使用可变状态,但是现在我只是想知道为什么这不起作用?在我看来,它无法记住部分应用的参数。

1 个答案:

答案 0 :(得分:5)

您有一个拼写错误:(r:l)应为(r::l):运算符表示“属于类型”,即r:l表示您告诉编译器r类型为l::运算符的意思是“将此前置在此列表的前面”:r::l表示“将r添加到列表l的前面”。

你在两个地方犯了这个错误:loop (r:l)应该是loop (r::l),而另一行是win_cps (r:l)应该是win_cps (r::l)