let sprite = pipe4 sprite_start blanks (manyTill attribute newline) blanks (fun a b c _ -> Sprite(a,c))
let sprites =
let rec y f x = f (y f) x // The Y Combinator
//let rec sprites_up = many1Indents sprite sprites_up |>> (fun x -> SubSprites x) // Does not work.
let sprites_up = y (fun f -> many1Indents sprite f |>> (fun x -> SubSprites x))
many1Indents sprite sprites_up
Вот пример из компилятора для маленькой библиотеки игр, которую я делаю на F #. Более конкретно, в приведенном выше примере мне нужно, чтобы sprites_up вызывал сам себя рекурсивно, иначе анализатор отступов не будет работать правильно.
Без Y Combinator я не смог бы правильно выполнить синтаксический анализатор и должен был бы написать что-то вроде этого:
let sprites_up4 = many1Indents sprite error |>> (fun x -> SubSprites x)
let sprites_up3 = many1Indents sprite sprites_up4 |>> (fun x -> SubSprites x)
let sprites_up2 = many1Indents sprite sprites_up3 |>> (fun x -> SubSprites x)
let sprites_up1 = many1Indents sprite sprites_up2 |>> (fun x -> SubSprites x)
let sprites_up = many1Indents sprite sprites_up1 |>> (fun x -> SubSprites x)
Не было бы отличного решения, Y Combinator действительно спас меня там. Хотя, конечно, это было не первое, что пришло в голову.