redo from jekor's Haskell From Scratch Series