<div dir="ltr"><div>I'm writing a wrapper around ekg which provides an MTL-style class for recording metrics [1], and now I'm trying to figure out how to make the class usable for clients.</div><div><br></div><div>I'm conflicted on the numerous ways to approach the problem. I would like to provide the best UX for the library, and want to consider viewpoints other than my own.</div><div><br></div><div>Currently, the class is:</div><div><br></div><div>class MonadMetrics m where getMetrics :: m Metrics</div><div><br></div><div>I currently don't provide any concrete transformer, instead requiring that users define it for their own stacks. I'd like to make it easier to use.</div><div><br></div><div>I can provide a concrete transformer</div><div><br></div><div>newtype MetricT m a = MetricT (ReaderT Metrics m a)<br>instance Monad m => MonadMetrics (MetricT m) where getMetrics = MetricT ask </div><div><br></div><div>and then provide a wide variety of pass through instances. This approach requires a large amount of boilerplate, and for any instances I forget to provide, will require that clients make their own orphan instances. It also incurs additional dependencies just for writing instances.</div><div><br></div><div>I can provide a more abstract transformer and a more general Metrics class:<br><br>class HasMetrics r where metrics :: Lens' r Metrics</div><div><br>newtype MetricT2 m a = MetricT2 (m a)<br>instance (MonadReader r m, HasMetrics r) => MonadMetrics (MetricT2 m) where<br> getMetrics = MetricT (view metrics)</div><div><br></div><div>but this still requires those pass through instances.</div><div><br></div><div>Finally, I can scrap `MonadMetrics` as anything other than a class alias:</div><div><br></div><div>class (MonadReader r m, MonadIO m, HasMetrics r) => MonadMetrics r m<br>instance (MonadReader r m, MonadIO m, HasMetrics r) => MonadMetrics r m</div><div><br></div><div>but now I have UndecidableInstances and a multiparam type class, and I'm not sure how well this actually plays out in the wild.</div><div><br></div><div>What are your thoughts on this issue?</div><br clear="all"><div><div class="gmail_signature"><div dir="ltr"><div>Matt Parsons</div><div><br></div><div>[1]: <a href="https://github.com/sellerlabs/monad-metrics">https://github.com/sellerlabs/monad-metrics</a><br></div></div></div></div>
</div>