Search code examples
haskellstrong-typing

How do I keep Haskell's Strong Typing Flexible?


I have been writing a growing code base in Haskell. My problem is that I have added type signatures to functions based on what GHCI tells me they should be.

The problem is now that I have a growing codebase, as soon as I change one thing, my code breaks all over the place and I am consumed with tracking down all of the problems.

Are the types derived by loading a module in ghci too specific? How do I decide which type or type classes to use in my signatures to leverage the power of strong typing with some flexibility? (i.e. not spending an hour propagating minor changes?).


Solution

  • The problem is now that I have a growing codebase, as soon as I change one thing, my code breaks all over the place and I am consumed with tracking down all of the problems.

    This is actually advertised as a feature in Yesod (a Haskell web framework). Suppose I have specified the following routing specification:

    /blog/#String         BlogR   GET
    

    And I decide I want to change it to

    /blog/#Date/#String   BlogR   GET
    

    As soon as I make this change to the routes, the compiler will tell me everywhere that I have broken my code. I will be forced to update the getBlogR function - changing its input type so it also accepts a Date. I will also be forced to update any place where I use type safe URLs in my templates, which would look something like @{BlogR (slug p)} -> @{BlogR (date p) (slug p)}.

    This is considered a Good Thing, because the type checker is helping you to find problems introduced by the changes you made.


    Now, regarding ghci.

    ghci> let shew = show
    ghci> :t shew
    shew :: () -> String
    ghci> :t show
    show :: Show a => a -> String
    

    It is sometimes true that ghci chooses annoying defaults. This, however, can be alleviated.

    ghci> :set -XNoMonomorphismRestriction
    ghci> let shew = show
    ghci> :t shew
    shew :: Show a => a -> String
    

    While using ghci to discover the type of a function is great for beginners, I wouldn't recommend relying on ghci. Learn what the type signatures mean, and how to discover them yourself. In fact, start writing a function by first writing the type signature you intend it to have. It only takes a small investment of time to learn this skill, and it is a great boon to programming when you can use Haskell's type system to your advantage.