External Publication
Visit Post

Lazily consuming a self-referential linked list

Haskell Community [Unofficial] May 19, 2026
Source

VegOwOtenks:

go :: [q] -> s -> (q -> s -> [q] -> ([q], s)) -> ([q], s)
go qs s0 f = case qs of
  [] -> ([], s0)
  q:rest -> let
      (qs1, s1) = f q s0 qs2 -- why is this qs2 and not rest?
      (qs2, s2) = go rest s1 f -- why is this rest and not qs1?
    in (qs1, s2) -- why is this qs1 and not qs2?

I think you could condense go to look something like:

go :: [q] -> s -> (q -> s -> [q] -> ([q], s)) -> ([q], s)
go qs s0 f = case qs of
  [] -> ([], s0)
  q:rest -> let
      (qs1, s1) = f q s0 rest
      newQ = rest ++ qs1
      in go newQ s1 f

Unless I’m missing something.

Your original approach causes an infinite loop because the recursive call to go depends on s1 whose result depends on qs2 which is produced by go.

Discussion in the ATmosphere

Loading comments...