Modified with StateT + ST monad (close #8)