Solving stuck type families with a TC plugin

Sandy Maguire sandy at sandymaguire.me
Sun Aug 4 17:06:14 UTC 2019


Hi all,

I'm attempting to use a plugin to solve a generic

type family CmpType (a :: k) (b :: k) :: Ordering

by doing some sort of arbitrary hashing on `a` and `b` and ensuring they're
the same.

In the past, I've been successful at getting GHC to unify things by
emitting new wanted CNonCanonical cts. This sort of works:


mkWanted :: TyCon -> CompareType -> TcPluginM Ct
mkWanted cmpType cmp = do
  (ev, _) <- unsafeTcPluginTcM
             . runTcSDeriveds
             $ newWantedEq
                 (cmpTypeLoc cmp)
                 Nominal
                 (cmpTypeType cmp)
                 (doCompare cmp)
  pure $ CNonCanonical ev


Which is to say that this will compile:


foo :: Proxy 'EQ
foo = Proxy @(CmpType 2 2)


So far so good! However, this acts strangely. For example, if I ask for bar
with the incorrect type:


bar :: Proxy 'GT
bar = Proxy @(CmpType 2 2)


I get the error:

    • Couldn't match type ‘CmpType 2 2’ with ‘'GT’
      Expected type: Proxy 'GT
        Actual type: Proxy (CmpType 2 2)

when I would expect

    • Couldn't match type ‘'EQ’ with ‘'GT’


This is more than just an issue with the error messages. A type family that
is stuck on the result of CmpType, even after I've solved CmpType via the
above!


type family IsEQ (a :: Ordering) :: Bool where
  IsEQ 'EQ = 'True
  IsEQ _   = 'False

zop :: Proxy 'True
zop = Proxy @(IsEQ (CmpType 2 2))


    • Couldn't match type ‘IsEQ (CmpType 2 2)’ with ‘'True’
      Expected type: Proxy 'True
        Actual type: Proxy (IsEQ (CmpType 2 2))


Any suggestions for what I might be doing wrong, and how to convince GHC to
make `zop` work properly? Thanks!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20190804/c1b0b089/attachment.html>


More information about the ghc-devs mailing list