2016-08-13 3 views
2

Код:Почему в этом примере синтаксического анализатора CPS используется параметр curries?

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, и я экспериментировал в F # первый. Если бы я действительно хотел сделать это в F #, я бы использовал изменчивое состояние, но на данный момент мне просто интересно, почему это не работает? Мне кажется, что он не может вспомнить частично примененные параметры.

ответ

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).

+0

Вы правы. Как неловко. –