An Algebraic Approach to Data Types, Program Verification, and Program Synthesis