Let’s first start with what scanr is trying to accomplish. The left and right versions of scan are the same thing as a fold except that we hold onto each state value we produce, ultimately returning an entire list of state values, instead of only returning the final state value like we would in a fold.
Let’s look at that first line:
scanr f q0 (x:xs) = f x q : qs
so we know this is the branch that gets run when the 3rd argument actually has at least one element in it, which we call x. f is a function that takes the current element + the state so far and returns the resulting state. So we’re going to call f with the our one element x, plus the “current state” q and we’re going to cons that with the list of preceeding states that we’ve already calculated, qs. Of course we haven’t defined q or qs yet, those come in the second line:
where qs@(q:_) = scanr f q0 xs
qs@(q:_) is a shorthand. You can kind of think of it the same as
where
qs = scanr f q0 xs
(q:_) = qs
So q is just the first element of qs, and qs is our recursive call to scanr where this time we pass in xs (the tail of our original input). That recursion where we pass in the tail is going to help us iterate through all of our input list.
Did that help?