Successfully reported this slideshow.
Writing Better   Haskell
TL;DR:You can start off  bad, and get better
Case Study: Kit
$ cabal install kitDependency manager for Obj-C code
Kit’s Origins• 80% of the functionality needed produced  in one (alcohol fueled) weekend• Very little Haskell knowledge• N...
It’s bad code.
How bad?• IO everywhere• Very little usage of the standard library, or  any other libraries• General ugliness
It could only get better.
Clearing out IO
Kit’s IO• Producing Xcode projects - project files,  config files• Reading Specs - a configuration file for a  Kit
Writing FilescreateKitConfig :: Config -> IO ()
FS Actions• data FSAction =• FileCreate FilePath String |• Symlink FilePath FilePath |• InDir FilePath FSAction• runAction...
FSActioncreateKitConfig :: Config -> FSActionsetupKitDirectory :: KitSpec ->[FSAction]
Next: Cleaning IO• Reader monad for specifying the  Environment• Writer monad for pure logging• State monad for pure repos...
Learning the   StdLib   [and hackage]
Unfolding        Dependencies• treeDependencies :: Kit -> Tree Kit• totalDependencies :: Kit -> [Kit]• Order is actually i...
Unfolding        Dependencies• Preserve order: lowest level deps first, keep  dep order listing from Spec file• No duplicates
Unfolding        Dependenciesnub . concat . reverse . drop 1 . levels
Other learns:• Globbing: • Shelling out to ruby, vs • the glob package• CmdArgs: • Pattern match on arrays of args, vs • C...
General Ugliness    Tidying up imports
Prefix headers• Used in [Obj-]C applications to provide  global imports.• Application-specific base library
Before• import System.FilePath.Posix• import System.Directory• import Control.Applicative• import Control.Monad• In every ...
Aftermodule Kit.Util( module Kit.Util, module Control.Applicative, module Control.Monad, module System.Directory, module S...
After• import Kit.Util
So, is it good yet?
No.• Plug through WriterT for Logging• Remove IO from the Monad stack• When IO is gone, define invariants in  quickcheck pr...
Upcoming SlideShare
Loading in …5
×

Writing Better Haskell

871 views

Published on

Beginner level talk, general tips on getting better at writing haskell code.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Writing Better Haskell

  1. 1. Writing Better Haskell
  2. 2. TL;DR:You can start off bad, and get better
  3. 3. Case Study: Kit
  4. 4. $ cabal install kitDependency manager for Obj-C code
  5. 5. Kit’s Origins• 80% of the functionality needed produced in one (alcohol fueled) weekend• Very little Haskell knowledge• No internet access, no guidance.
  6. 6. It’s bad code.
  7. 7. How bad?• IO everywhere• Very little usage of the standard library, or any other libraries• General ugliness
  8. 8. It could only get better.
  9. 9. Clearing out IO
  10. 10. Kit’s IO• Producing Xcode projects - project files, config files• Reading Specs - a configuration file for a Kit
  11. 11. Writing FilescreateKitConfig :: Config -> IO ()
  12. 12. FS Actions• data FSAction =• FileCreate FilePath String |• Symlink FilePath FilePath |• InDir FilePath FSAction• runAction :: FSAction -> IO ()
  13. 13. FSActioncreateKitConfig :: Config -> FSActionsetupKitDirectory :: KitSpec ->[FSAction]
  14. 14. Next: Cleaning IO• Reader monad for specifying the Environment• Writer monad for pure logging• State monad for pure repository manipulation
  15. 15. Learning the StdLib [and hackage]
  16. 16. Unfolding Dependencies• treeDependencies :: Kit -> Tree Kit• totalDependencies :: Kit -> [Kit]• Order is actually important.
  17. 17. Unfolding Dependencies• Preserve order: lowest level deps first, keep dep order listing from Spec file• No duplicates
  18. 18. Unfolding Dependenciesnub . concat . reverse . drop 1 . levels
  19. 19. Other learns:• Globbing: • Shelling out to ruby, vs • the glob package• CmdArgs: • Pattern match on arrays of args, vs • CmdArgs package
  20. 20. General Ugliness Tidying up imports
  21. 21. Prefix headers• Used in [Obj-]C applications to provide global imports.• Application-specific base library
  22. 22. Before• import System.FilePath.Posix• import System.Directory• import Control.Applicative• import Control.Monad• In every damn file.
  23. 23. Aftermodule Kit.Util( module Kit.Util, module Control.Applicative, module Control.Monad, module System.Directory, module System.FilePath.Posix ) where
  24. 24. After• import Kit.Util
  25. 25. So, is it good yet?
  26. 26. No.• Plug through WriterT for Logging• Remove IO from the Monad stack• When IO is gone, define invariants in quickcheck properties• Learn how to specify those properties through types

×