Reader
. It's so common that the Haskell community has started rapidly embracing it as the wrapper for applications. You can have global and local Reader
s, but we'll be focusing here on the global one for our application.Env
, but that can conflict with standard terminology for environment variables, which environment an application is running in (test, development, staging, production), and so on. We have opted to call this Config
.Config
s, just fieldsConfig
Config.get
pulls out a value from the Config
. It knows which value you want because of the expected constructor (Web.Host
) on the left side of the <-
.MonadRIO
is a constraint defined in our application. It's an alias for the very common scenario in this style of wanting both MonadIO m
and MonadReader cfg m
. RIO
) depends on having functions available ambiently in this way. One common case is with logging, which needs a LogFunc
ready for use. Has
. This is because we're using the Has library to clean up some of the boilerplate associated with creating so many constraints.Config
record. The first step is to ensure that the type is unique to the application, wrapping common types in newtype
:Config
itself:makeLenses
declaration, you automagically get a lens (superpowered accessor) for the new field called port