Buenas, leyendo el paper de "Monads for functional programming" afirman en la sección 5.11 que usualmente un parser monádico no actua de forma lazy sobre la entrada, poniendo como ejemplo a reiterate m.
Particularmente se toma
reiterate :: M a -> M [a]
reiterate m = (m >>= \a reiterate m >>= \x return (a : x)) '\' return []
donde llamo a '\' a la elección sesgada de la sección 5.8.
Entiendo que dado el secuenciamiento de >>=, y teniendo return [] a la derecha, esta definición de reiterate debe terminar la recursión hasta dar el primer resultado.
Luego, redefinen reiterate como:
reiterate m = guarantee ((m >>= \a reiterate m >>= \x return (a : x)) '\' return [])
donde
guarantee m x = let u = m x in (fst (head u), snd (head u)) : tail u
El paper dice luego, que esta definición hace que reiterate pueda ejecutarse de forma lazy, pero no me queda claro como. Particularmente, para poder ejecutar fst (head u), la computación m x (en este caso, reiterate) debe producir al menos un elemento de la lista, pero reiterate no produce nada hasta terminar la recursión.
Entonces, de que forma utilizar guarantee mejora el comportamiento respecto a lazy evaluation?