Skip to content

Wingman is still flummoxed by GADT evidence #1884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
isovector opened this issue Jun 4, 2021 · 1 comment · Fixed by #1885
Closed

Wingman is still flummoxed by GADT evidence #1884

isovector opened this issue Jun 4, 2021 · 1 comment · Fixed by #1885
Labels
component: wingman type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..

Comments

@isovector
Copy link
Collaborator

{-# LANGUAGE DataKinds #-}

import Data.Kind

data Nat = Z | S Nat

data HList (ls :: [Type]) where
  HNil :: HList '[]
  HCons :: t -> HList ts -> HList (t ': ts)

data ElemAt (n :: Nat) t (ts :: [Type]) where
  AtZ :: ElemAt 'Z t (t ': ts)
  AtS :: ElemAt k t ts -> ElemAt ('S k) t (u ': ts)

lookMeUp :: ElemAt i ty tys -> HList tys -> ty
lookMeUp AtZ (HCons t' hl) = _
lookMeUp (AtS ea') (HCons _ hl') = lookMeUp ea' hl'

Wingman should be able to fill in the hole with t'. GHC knows this:

 Found hole: _ :: ty
 Relevant bindings include
    hl :: HList ts1 (bound at /home/sandy/prj/tesths/src/Lib.hs:19:24)
    t' :: t (bound at /home/sandy/prj/tesths/src/Lib.hs:19:21)
    lookMeUp :: ElemAt i ty tys -> HList tys -> ty
      (bound at /home/sandy/prj/tesths/src/Lib.hs:19:1)
  Constraints include
    tys ~ (t : ts1) (from /home/sandy/prj/tesths/src/Lib.hs:19:15-25)
    i ~ 'Z (from /home/sandy/prj/tesths/src/Lib.hs:19:10-12)
    tys ~ (ty : ts) (from /home/sandy/prj/tesths/src/Lib.hs:19:10-12)

We can learn this by unifying (t : ts1) ~ tys ~ (ty : ts) therefore t ~ ty and ts1 ~ ts. But that information never makes it to the Wingman unifier. Instead, our substition set looks like:

   In scope: InScope {t ts}
   Type env: [a1fDf :-> (':) @* t ts, a1fDk :-> t, a1fDl :-> ts]
   Co env: []]
!!!subst: [TCvSubst
   In scope: InScope {ty ts}
   Type env: [a1fDe :-> ty, a1fDf :-> (':) @* ty ts, a1fDh :-> ts]
   Co env: []]
!!!subst: [TCvSubst In scope: InScope {} Type env: [a1fDd :-> 'Z] Co env: []]

The relevant bits here are the substitutions of a1fDf :-> (':) @* ty ts and a1fDf :-> (':) @* t ts. But it's weird --- two separate substitutions for the same variable? Is this substitution not being persisted somehow?

@isovector isovector added type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc.. component: wingman labels Jun 4, 2021
@isovector
Copy link
Collaborator Author

Digging in deeper, this is the evidence we've got: [EqualityOfTypes i 'Z,EqualityOfTypes tys (ty : ts),EqualityOfTypes tys (t : ts)] which is absolutely right. So I think the issue is that we're not applying the substitution to the evidence.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: wingman type: bug Something isn't right: doesn't work as intended, documentation is missing/outdated, etc..
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant