Skip to content

Conversation

@danbroooks
Copy link
Contributor

@danbroooks danbroooks commented Apr 28, 2021

Before submitting your PR, check that you've:

  • Documented new APIs with Haddock markup
  • Added @since declarations to the Haddock
  • Ran stylish-haskell on any changed files.
  • Adhered to the code style (see the .editorconfig file for details)

After submitting your PR:

  • Update the Changelog.md file with a link to your PR
  • Bumped the version number if there isn't an (unreleased) on the Changelog
  • Check that CI passes (or if it fails, for reasons unrelated to your change, like CI timeouts)

Closes #1166

I've opened this as a draft PR with a view towards getting some feedback on it still. I think everything here should be fine for addressing that ticket, but there might be something I have overlooked here. I will annotate what I've got so far.

I have also opened this PR against master as it is not a super invasive change, and I would be happy to deal with porting it forward into the persistent-2.13 branch after it is merged in. Alternatively if it is preferred that this PR goes against that branch, and is backported to master, I'd be happy to do that as well.

It may also make sense for this to just go into 2.13 like my other recent change 👍

@danbroooks danbroooks changed the title 1166 ticked types Support promoted types in Quasi Quoter Apr 28, 2021
let UserName = #name
OrganizationName = #name
DogName = #name
-}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be some more stuff to do here for this test maybe ... for now I have something that just asserts that it typechecks 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - let's check the type of the field accessors and the EntityFields.

Still should jsut be a compilation check, but something like:

let mkTransfer :: CustomerId -> MoneyAmount 'CustomerOwned 'Debt -> CustomerTransfer
    mkTransfer = CustomerTransfer
    getAmount :: CustomerTransfer -> MoneyAmount 'CustomerOwned 'Debt
    getAmount = customerTransferMoneyAmount

mEmbedded ents (FTTypeCon Nothing (EntityNameHS -> name)) =
maybe (Left Nothing) Right $ M.lookup name ents
mEmbedded ents (FTTypePromoted (EntityNameHS -> name)) =
maybe (Left Nothing) Right $ M.lookup name ents
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this. I basically just mirrored what is done for FTTypeCon when there is no module (ie the case above).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - I'd say let's go with a Left Nothing on all cases here. If we hit this, it means we're trying to determine whether we need an embedded entity reference, which we shouldn't - the only place this could possibly be is if we've got an FTApp or similar, and we want the SQL type construction to proceed unchanged.

Suggested change
maybe (Left Nothing) Right $ M.lookup name ents
Left Nothing

Like, we'll have foo (Proxy 'User). That'll get turned into FTApp (FTypeCon Nothing "Proxy") (FTTypePromoted "User"). This code recurses and then finds that the corresponding EmbedEntityDef is for a User, even though that's totally wrong.

Copy link
Collaborator

@parsonsmatt parsonsmatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few changes I'd like on this before accepting it, but it is fantastic work - thank you so much!

I'm afraid the changes I put into #1256 are going to be a massive conflict here. So let's get this merged in to master, we can release it as a patch bump since it's just a change to the QQ and purely additive. Then I'll work on getting it merged into persistent-2.13.

in case T.breakOnEnd "." t of
(_, "") -> FTTypeCon Nothing t
("", _) -> FTTypeCon Nothing t
(a, b) -> FTTypeCon (Just $ T.init a) b
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great 👍🏻

mEmbedded ents (FTTypeCon Nothing (EntityNameHS -> name)) =
maybe (Left Nothing) Right $ M.lookup name ents
mEmbedded ents (FTTypePromoted (EntityNameHS -> name)) =
maybe (Left Nothing) Right $ M.lookup name ents
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - I'd say let's go with a Left Nothing on all cases here. If we hit this, it means we're trying to determine whether we need an embedded entity reference, which we shouldn't - the only place this could possibly be is if we've got an FTApp or similar, and we want the SQL type construction to proceed unchanged.

Suggested change
maybe (Left Nothing) Right $ M.lookup name ents
Left Nothing

Like, we'll have foo (Proxy 'User). That'll get turned into FTApp (FTypeCon Nothing "Proxy") (FTTypePromoted "User"). This code recurses and then finds that the corresponding EmbedEntityDef is for a User, even though that's totally wrong.

FTApp x y ->
ftToType x `AppT` ftToType y
FTList x ->
ListT `AppT` ftToType x
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👨🏻‍🍳

-- {-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}

module Database.Persist.TH.KindEntitiesSpec where
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

beautiful tests <3

let UserName = #name
OrganizationName = #name
DogName = #name
-}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah - let's check the type of the field accessors and the EntityFields.

Still should jsut be a compilation check, but something like:

let mkTransfer :: CustomerId -> MoneyAmount 'CustomerOwned 'Debt -> CustomerTransfer
    mkTransfer = CustomerTransfer
    getAmount :: CustomerTransfer -> MoneyAmount 'CustomerOwned 'Debt
    getAmount = customerTransferMoneyAmount

sqlType _ = SqlInt64

instance PersistField (MoneyAmount a b) where
toPersistValue (MoneyAmount n) = PersistRational n
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this PeristRational lines up with the SqlInt64 type you specified

@danbroooks danbroooks marked this pull request as ready for review May 4, 2021 17:59
- Correct instances for MoneyAmount
- Add some additional compiler checks to spec
- Removed commented out code
- Remove redundant logic in mEmbedded
@danbroooks danbroooks force-pushed the 1166-ticked-types branch from 61b5361 to 2e11e0b Compare May 4, 2021 18:25
Copy link
Collaborator

@parsonsmatt parsonsmatt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@parsonsmatt
Copy link
Collaborator

All good to merge?

@danbroooks
Copy link
Contributor Author

Yeah all good 👍 I'm happy to do the merge/conflict resolution into persistent-2.13 if you want (I can do it straight after this PR is merged if it is going in now), I'm also happy to leave it to you 😄

@parsonsmatt
Copy link
Collaborator

That would be really helpful, thank you 🙌🏻

@parsonsmatt parsonsmatt merged commit cb7283f into yesodweb:master May 4, 2021
@danbroooks danbroooks deleted the 1166-ticked-types branch May 5, 2021 16:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

model TH support of kinds (promoted types)

2 participants