Using Haskell's type system to enforce modularity

haskell, type-systems, types

Solution

I am picturing a higher-level monad that would be limited to direct URL handlers and would be able to compose calls to the DB monad and the IO monad.

You can certainly achieve this, and get very strong static guarantees about the separation of the components.

At its simplest, you want a restricted IO monad. Using something like a "tainting" technique, you can create a set of IO operations lifted into a simple wrapper, then use the module system to hide the underlying constructors for the types.

In this way you'll only be able to run CGI code in a CGI context, and DB code in a DB context. There are many examples on Hackage.

Another way is to construct an interpreter for the actions, and then use data constructors to describe each primitive operation you wish. The operations should still form a monad, and you can use do-notation, but you'll instead be building a data structure that describes the actions to run, which you then execute in a controlled way via an interpreter.

This gives you perhaps more introspection than you need in typical cases, but the approach does give you full power to insspect user code before you execute it.

Problem

I'm thinking about ways to use Haskell's type system to enforce modularity in a program. For example, if I have a web application, I'm curious if there's a way to separate all database code from CGI code from filesystem code from pure code. For example, I'm envisioning a DB monad, so I could write functions like: ``` countOfUsers :: DB Int countOfUsers = select "count(*) from users" ``` I would like it to be impossible to use side effects other than those supported by the DB monad. I am picturing a higher-level monad that would be limited to direct URL handlers and would be able to compose calls to the DB monad and the IO monad. Is this possible? Is this wise? Update: I ended up achieving this with Scala instead of Haskell: http://moreindirection.blogspot.com/2011/08/implicit-environment-pattern.html

Original source