Should databases be viewed as Monads?

Because any kind of persistence updates/inserts/deletes represents in some sense a kind of state change in a database, it makes me wonder whether databases can be considered monads. We say the same about monads in functional programming.

What one can possibly gain or lose while designing a system with such thought process?


Not really.

A database is a facility for the structured and organized storage and retrieval of data. A monad is a way to communicate with that database in a manner that preserves functional purity.

Think of the monad as a converter from the pure, immutable, mathematical world of the functional programming language; to the impure, mutable world of I/O. Because your mutable side effects are sequestered behind the monad, you can “pretend” that you’re still living in a perfect, immutable world on the other side of the monad.

But, at the end of the day, it’s still just a monad. There can be anything on the mutable side of that monad: a database, a console, another computer running Eliza.


Databases are frequently modeled as monads in functional programming. HaskellDb, Quill, Slick, and Doobie are some examples I’m aware of. You can argue there’s a difference between the database itself and the programming interface to the database. I’m not sure that’s a useful distinction in this context.

More precisely, an operation on a database table is frequently modeled as a monad. So the return function wraps some table representation (like a record or class) into an internal query form that can be used for further transformations (taking a record to a Query record for example). The bind function (called >>= in Haskell) transforms the wrapped query action using the given function. For example, adding a WHERE clause to the query.

Since most collection types are also monads, this enables treating database tables like regular collections. You can use the same simplifications you use for other monads: Control.Monad library, do notation, for comprehensions, composition, etc. The structure of your query is type checked. If you add macros to the mix, like Quill does, the SQL can be generated at compile time. It’s quite a useful abstraction.


Usually, a Monad represents some sort of way of doing computations. For example, Maybe is a monad that enables computations to fail. [] is a computation that allows multiple results. IO is a monad that allows communication with the nebulous RealWorld.

A database isn’t really that. You could have State DataBase, which would be a computation with one mutable variable (namely, a DataBase), but the DataBase itself probably can’t been seen as monad.

Lookup return and >>=. Every monad needs to have these. Do databases have them?

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *