それと私が書いたコードは以下のような感じです(若干略していますが)。

data VM = VM Stack RegisterTable

runVM :: VM -> Codes -> VM
runVM vm codes = selectUnChangedVM $ generateAllVM vm codes
    where
      selectUnChangedVM :: [VM] -> VM
      selectUnChangedVM (vm1:vm2:vms)
          | vm1 == vm2 = vm1
          | otherwise = selectUnChangedVM (vm2:vms)
      generateAllVM :: VM -> Codes -> [VM]
      generateAllVM vm codes = iterate (execOne codes) vm

execOne :: Codes -> VM -> VM
execOne codes vm = newvm
    where
      code = selectCode vm codes
      newvm = execCode code vm

やっていることは以下の通りです.

  (1) 1クロックごとのVMの状態を持つ無限ストリームを生成
  (2) その中で次のクロックに移っても状態が変わっていないVMを見付けてそのVMを返す