Preventing inert caching in TC plugin?

Adam Gundry adam at well-typed.com
Sat Feb 4 12:49:46 UTC 2023


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


-- 
Adam Gundry, Haskell Consultant
Well-Typed LLP, https://www.well-typed.com/

Registered in England & Wales, OC335890
27 Old Gloucester Street, London WC1N 3AX, England



More information about the ghc-devs mailing list