Dependent Types In Haskell: Theory And Practice