run (error "urk!") will error out.
Instead, run [error "urk!"] will successully return 1.
Why? Because run is defined by cases: empty list, nonempty list. Hence it has to evaluate its argument just enough to know if the list is empty or not. We don't have to evaluate the error in [error "urk!"] to see that the list is not empty, but we have if error "urk!" is the list itself.
In the posted code, we evaluate run (cycle out) so we have to check if cycle out is empty or not. This triggers the evaluation of cycle out, which in turn triggers the evaluation of out (cycle is defined by cases as well). Since out is what we are defining, we get an infinite recursion.
It happens that this infinite recursion is easy enough to be spotted by the GHC runtime, which kindly emits an exception <<loop>> instead of perform the non terminating computation.
To stress the concept, consider these functions
strictPrepend :: [Int] -> [Int]
strictPrepend [] = 1 : []
strictPrepend (x:xs) = 1 : x : xs
lazyPrepend :: [Int] -> [Int]
lazyPrepend xs = 1 : xs
One might think that these functions are equal. Indeed, the first one is defined by cases, but in both cases it performs the same operation (prepending 1), so it looks equivalent to the second.
Concretely, we have that for all bottom free lists ys, the result of strictPrepend ys is the same as lazyPrepend ys.
In the presence of bottoms (like error "..", undefined, or infinite recursion), these functions differ. For instance lazyPrepend undefined = 1 : undefined, while strictPrepend undefined = undefined since it raises an exception before producing the initial element 1.
Consequently,
let ys = strictPrepend ys
zs = lazyPrepend zs
defines ys as bottom (infinite recursion) but zs = 1:1:1:1:..... is an infinite sequence of 1s. This is the effect of producing the 1 before needing to evaluate the argument.