<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><font face="Courier" class="">Hi everyone!</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">First of all, i don't know if this idea is already being discussed so if there's a discussion on this i'd like to follow.</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">To illustrate, first i want to create a class like:</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">class Has a t where</font></div><div class=""><font face="Courier" class=""> get :: t -> a</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">then i define instance for simple product type such as tuple:</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class=""><div class="">instance Has a (a, b) where</div><div class=""> get (a, _) = a</div><div class=""><br class=""></div><div class="">instance Has b (a, b) where</div><div class=""> get (_, b) = b</div></font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">...</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class="">You can image i will use th to make lots of instance for difference tuple size. Now if i want an extensible reader, i use Has class like this:</font></div><div class=""><font face="Courier" class=""><br class=""></font></div><div class=""><font face="Courier" class=""><div class="">someReader :: Has Int t => Reader t Int</div><div class="">someReader = do</div><div class=""> x <- ask</div><div class=""> return $ get x + 1</div><div class=""><br class=""></div><div class="">Then i can run it with any tuple with an Int field like:</div><div class=""><br class=""></div><div class="">runReader someReader (0 :: Int, "adad”) -- 1</div><div class=""><br class=""></div><div class="">This typeclass almost solved all problem of my network application: sometime’s i want ensure a logger, a sql backend and a http client pool in my monad’s environment, but i don’t want to fix my environment into a record.</div></font><font face="Courier" class=""><div class=""><br class=""></div><div class="">We can add a set :: a -> t -> t, or use lens to define Has, so that we can have extensible states.</div><div class="">We can also use Tagged to achieve something like:</div><div class=""><br class=""></div><div class="">(Has (Tagged “SqlBackEndOne” SqlBackEnd) t, Has (Tagged “SqlBackEndTwo" SqlBackEnd) t) => Reader t ()</div><div class=""><br class=""></div><div class="">It there a library doing this, maybe in lens? or there’re some drawbacks i didn’t notice? All ideas are welcomed!</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Cheers~</div><div class="">Winter</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div></font></div></body></html>