Preventing inert caching in TC plugin?

Sandy Maguire sandy at sandymaguire.me
Sat Feb 4 18:00:34 UTC 2023


Hi Adam,

Thakns for the pointer. Adding the type variable indeed seems to solve
the problem. Greatly appreciated!

Best,
Sandy

On Sat, 2023-02-04 at 12:49 +0000, Adam Gundry wrote:
> Hi Sandy,
> 
> I don't think you can easily prevent GHC from caching solutions to 
> specific constraints, and even if you could, the simplifier feels
> free 
> to common-up dictionaries with the same type and hence would
> potentially 
> introduce unintended semantic changes to the program.
> 
> You might be able to address at least the second issue by using
> implicit 
> parameters instead. But I think a more robust approach would be to 
> introduce an extra type parameter:
> 
>      class KnownAnnotations a where
>        rawAnnotationsVal :: [Annotation]
> 
> Now each rawAnnotationsVal call site will introduce a fresh
> unification 
> variable α and the wanted constraint `KnownAnnotations α`. Your
> plugin 
> can spot this constraint and solve it, while leaving α
> uninstantiated. 
> Hence each call site will have a different constraint type, and the 
> problems should go away.
> 
> Perhaps you could even make the parameter invisible/inferred, so it 
> wouldn't change the user-visible API. Something like this might work,
> but I haven't tested it:
> 
>      type KnownAnnotations :: forall {a} . Constraint
>      class KnownAnnotations where
>        rawAnnotationsVal :: [Annotation]
> 
> Hope this helps,
> 
> Adam
> 
> 
> 
> On 04/02/2023 09:29, Sandy Maguire via ghc-devs wrote:
> > Hi all,
> > 
> > I'm working on a little TC plugin that solves the following class:
> > 
> > ```haskell
> > class KnownAnnotations where
> >    rawAnnotationsVal :: [Annotation]
> > ```
> > 
> > Like `HasCallStack`, the result of `KnownAnnotations` is unique to
> > each
> > callsite. Thus, I am trying to prevent my TC plugin from adding the
> > solved constraint to the inert set.
> > 
> > As an example, the following program:
> > 
> > ```
> > t2 :: ([Annotation], Int)
> > t2 = (rawAnnotationsVal, test2)
> > 
> > t3 :: ([Annotation], Int)
> > t3 = (rawAnnotationsVal, test3)
> > ```
> > 
> > dumps this output with `-ddump-cs-trace`:
> > 
> > ```
> > 
> > Step 1[l:0,d:0] Kept as inert:
> >      [WD] $dKnownAnnotations_a18UB {0}:: KnownAnnotations
> > Step 2[l:0,d:0] Dict equal (keep inert):
> >      [WD] $dKnownAnnotations_a18UD {0}:: KnownAnnotations
> > ```
> > 
> > Is there some trick to prevent the inert caching for these solved
> > wanteds?
> > 
> > Cheers,
> > Sandy
> 
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 659 bytes
Desc: This is a digitally signed message part
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20230204/f721da6f/attachment.sig>


More information about the ghc-devs mailing list