can-i-haz: Generic implementation of the Has pattern

[ bsd3, control, library ] [ Propose Tags ]

Please see the README on GitHub at https://github.com/0xd34df00d/can-i-haz#readme


[Skip to Readme]
Versions [faq] 0.1.0.0, 0.1.0.1
Change log ChangeLog.md
Dependencies base (>=4.7 && <5) [details]
License BSD-3-Clause
Copyright 2019 Georg Rudoy
Author Georg Rudoy
Maintainer 0xd34df00d@gmail.com
Category Control
Home page https://github.com/0xd34df00d/can-i-haz#readme
Bug tracker https://github.com/0xd34df00d/can-i-haz/issues
Source repo head: git clone https://github.com/0xd34df00d/can-i-haz
Uploaded by 0xd34df00d at Sat Aug 3 21:10:30 UTC 2019
Distributions NixOS:0.1.0.1
Downloads 54 total (54 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Hackage Matrix CI
Docs available [build log]
Last success reported on 2019-08-03 [all 1 reports]

Modules

[Index] [Quick Jump]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for can-i-haz-0.1.0.1

[back to package description]

can-i-haz

Build Status Hackage Stackage LTS Stackage Nightly

Generic implementation of the Has-pattern (mostly useful with MonadReader).

Motivation

Assume there are two types representing the MonadReader environments for different parts of an app:

data DbConfig = DbConfig { .. }
data WebConfig = WebConfig { .. }

as well as a single type containing both of those:

data AppEnv = AppEnv
  { dbConfig :: DbConfig
  , webConfig :: WebConfig
  }

What should be the MonadReader constraint of the DB module and web module respectively?

  1. It could be MonadReader AppEnv m for both, introducing unnecessary coupling.
  2. Or it could be MonadReader DbConfig m for the DB module and MonadReader WebConfig m for the web module respectively, but combining them becomes a pain.

Or, it could be MonadReader r m, Has DbConfig r for the DB module, where Has class allows projecting DbConfig out of some r, and similarly for the web module! This approach keeps both modules decoupled, while allowing using them in the same monad stack.

The only downside is that now one has to define the Has class and write tediuos instances for the AppEnv type (and potentially other types in case of tests).

The solution

This library saves you from this unnecessary boilerplate! The only thing you have to do is to append the deriving-clause:

data AppEnv = AppEnv
  { dbConfig :: DbConfig
  , webConfig :: WebConfig
  } deriving (Generic, Has DbConfig, Has WebConfig)

and use ask extract instead of ask (but this is something you'd have to do anyway).

Documentation

Perhaps the best source is the Haddock docs.