{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreieqytuitlgvrprfkhlbeipsfphvewffxwrmmkiev7eja43h2ce6fy",
"uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mm7gmu4itk72"
},
"path": "/t/lazily-consuming-a-self-referential-linked-list/14131#post_5",
"publishedAt": "2026-05-19T10:38:11.000Z",
"site": "https://discourse.haskell.org",
"tags": [
"TardisT"
],
"textContent": "VegOwOtenks:\n\n> The order is like this because it allows the list that is build-up to travel-backwards along the computation, like it would with TardisT. This enables cheap list-building (only cons, no concatenation) while preserving FIFO semantics.\n\nAh I see, that pretty neat! And beyond my skill level xD.\n\nI’ve had a bit more of a look and the circle I’m trying to square is the `(q → s →[q] → ([q],s))` function. The question is where do you get this `q` element from if `[q]` is empty?\n\nA minor change to the type signature to make it `(s → [q] → (s, [q]))` means then this function can also have some resposible logic for determining when to stop processing.\n\n\n run3 s0 [] _ = s0 -- queue is empty stop processing\n run3 s0 (q:qs) f = let\n (s1, newQ) = f s0 q\n in run3 s1 (newQ ++ qs) f\n -- | swap the order of the (++) and `use reverse` to get LIFO/FIFO behaviour\n\n test2 initState queue = run3 initState queue someFunc\n where someFunc s qElem\n -- | some rock solid cases that stops new list elements being generated indefinitely\n\n\nI’m not totally sure if that’s helpful as I’m struggling to grasp the behaviour of `Tardis`.\n\nPart of me feels like this is also achievable with nested `foldl/foldr`s but I haven’t looked that far into it.\n\nSorry I couldn’t help more!",
"title": "Lazily consuming a self-referential linked list"
}