
hi winter, This seems to be equivalent to the idea behind the multistate package [1], and its MultiReader type [2]. The `MonadMultiReader` class [3] does a lookup in a type-level (linked) list similar to your Tuple-focussed `Has` class. [1] https://hackage.haskell.org/package/multistate [2] hackage.haskell.org/package/multistate-0.7.1.1/docs/Control-Monad-MultiReader.html [3] https://hackage.haskell.org/package/multistate-0.7.1.1/docs/Control-Monad-Tr... The type signature would become
(MonadMultiReader (Tagged “SqlBackEndOne” SqlBackEnd) m, MonadMultiReader (Tagged “SqlBackEndTwo" SqlBackEnd) m) => m ()
Note that one main drawback of this approach is the necessity of dropping the functional dependency present on MultiReader (for MonadMultiReader). So the cost of automatic type-based lookup is less type inference; a simple example would be `mAsk >>= print` being ambiguous where `ask >>= print` is not (if the surrounding `m` is known). -- lennart On 22/11/16 04:30, winter wrote:
Hi everyone!
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.
To illustrate, first i want to create a class like:
class Has a t where get :: t -> a
then i define instance for simple product type such as tuple:
instance Has a (a, b) where get (a, _) = a
instance Has b (a, b) where get (_, b) = b
...
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:
someReader :: Has Int t => Reader t Int someReader = do x <- ask return $ get x + 1
Then i can run it with any tuple with an Int field like:
runReader someReader (0 :: Int, "adad”) -- 1
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.
We can add a set :: a -> t -> t, or use lens to define Has, so that we can have extensible states. We can also use Tagged to achieve something like:
(Has (Tagged “SqlBackEndOne” SqlBackEnd) t, Has (Tagged “SqlBackEndTwo" SqlBackEnd) t) => Reader t ()
It there a library doing this, maybe in lens? or there’re some drawbacks i didn’t notice? All ideas are welcomed!
Cheers~ Winter
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.