ekmett/lens

Declare Fields with Nested Records of types defined in same Splice

jjlehner opened this issue · 1 comments

declareFields [d| data A = A { aSubB :: B } data B = B { bB :: Int } |]

At the moment a splice like this does not work with "error B_0 is not in scope at a reify". Could there be possible solutions to fix this without having to split it into two declaration groups?

I agree that this is unfortunate. I believe the reason this happens is because we use reify here to check if a field contains type families:

containsTypeFamilies = go <=< D.resolveTypeSynonyms
where
go (ConT nm) = has (_FamilyI . _1 . _TypeFamilyD) <$> reify nm
go ty = or <$> traverse go (ty ^.. plate)

If we attempt to reify a field that hasn't been declared yet (e.g., B), then the error message above is the result. But we needn't fail here: we could just as well use recover to catch the reification failure and then conservatively assume that the type doesn't contain type families, which is a reasonable assumption most of the time.