Interaction trees: representing recursive and impure programs in Coq