[Haskell-cafe] An idea on extensible effects (anonymous record)
drkoster at qq.com
Tue Nov 22 14:14:41 UTC 2016
In my use case the type collision is definitely much less likely to happen, that is i often want to compose different effects like logger, sql and network ,etc. without Has class, i will have a hard time trying to compose `Reader Logger ()` and `Reader (Logger, HttpClient) ()`, since the concrete type can't be unified.
If i need two different Logger in environment, i still can do it without Tagged, i can define following newtypes in library site:
newtype StdLogger = StdLogger Logger
newtype FileLogger = FileLogger Logger
librarySite :: (Has StdLogger r, Has FileLogger r, MonadReader r m) => m ()
librarySite = do ...
stdLogger :: StdLogger <- asks get
fileLogger :: FileLogger <- asks get
And in application site i should supply a (StdLogger log1, FileLogger log2, ...).
Does above example illustrate my use case to you?
> On 22 Nov 2016, at 21:48, MarLinn <monkleyon at googlemail.com> wrote:
>>> Which brings us back to fclabels I suppose.
>> Can you elaborate this? I haven’t fully understand what is “incorporate the tag in the class from the start” . Thanks you.
> Suppose you have the original definitions
> class Has a t where
> get :: t -> a
> instance Has a (a, b) where
> get (a, _) = a
> instance Has b (a, b) where
> get (_, b) = b
> This creates a conflict if you use an (Int,Int) tuple because there are either no definitions or two conflicting definitions for get.
> As a solution you propose something along the lines of
> Has (Tagged “GetGetsFirst” a) (a,b)
> All I'm saying is that it seems useful or even necessary for sanity to combine Has and Tagged so that you can write
> Has “fst” a (a,b)
> The implementation should be something simple like
> class (KnownSymbol label) => Has label part whole | whole,label -> part where
> get :: Proxy label -> whole -> part
> -- 'Proxy label' is necessary because 'whole' and 'part' alone are not sufficient to determine the label. See (Int,Int).
> The obvious downside is that it doesn't make as much sense to have such a class now. I must admit I'm not too familiar with the alternatives, so I can't really compare it. But this was just a flaw I saw. Hope this cleared up what I meant.
>>>>> Does this differ significantly from fclabels or the upcoming OverloadedRecordFields extension? (Aside from being purely type driven, which has problems in your example if you compose a second Int into it.)
>>>> 1. Yes, it’s similar to OverloadedRecordFields but doesn’t force you to use a label, and you may use Tagged to label a field if you want.
>>>> 2. Yes, but again, you can use Tagged to allow same type in different disguise.
>>> I can see a potential problem because you can't hide instances. Once you define a Has-relationship, you can't cheaply change it. That could lead to conflicts, unless you hack around it with orphaned instances in a separate module. But you say you want to solve conflicts with tagging – so it would be reasonable to incorporate the tag in the class from the start. Which brings us back to fclabels I suppose.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe