Compiler optimizations are critical to the efficiency of modern functional programs. At the same time, optimizations that unintentionally change the semantics of programs can systematically introduce errors into programs that pass through them. The question of how to best verify that optimizations and other program transformations preserve semantics is an important one, given the potential for error introduction. Dependent types allow us to prove that properties about our programs are correct, as well as to design data types and interpreters in such a way that they are correct-by-construction. In this thesis, we explore the use of dependent types and intrinsically-typed definitional interpreters in progressively larger subsets of Monadic In...