Pattern matching in "do" requires a MonadFail context, which we don't have in
pure code. Instead, we'll use "case-of" to bind the part of the state that
we're interested in.
It used to only treat all trailing variables in read as varaible
declarings, but an array variable can be declared in other positions:
read -a foo -r
foo is a declared variable, and multiple such variables can be declared.