Skip to content

genericFromValue fails for a record with four or more fields #173

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
harendra-kumar opened this issue Feb 21, 2018 · 4 comments
Closed

genericFromValue fails for a record with four or more fields #173

harendra-kumar opened this issue Feb 21, 2018 · 4 comments

Comments

@harendra-kumar
Copy link
Contributor

For this record I cannot derive a FromValue instance:

data Resource = Resource
    { roleId      :: Text
    , resAge      :: Int32
    , resGender   :: Text
    , resLang     :: Text
    } deriving (Generic, Show)

It works if I remove the last field i.e. resLang otherwise it produces the following error:

    • No instance for (GraphQL.Internal.Value.FromValue.GenericFromValue
                         ((GHC.Generics.S1
                             ('GHC.Generics.MetaSel
                                ('Just "roleId")
                                'GHC.Generics.NoSourceUnpackedness
                                'GHC.Generics.NoSourceStrictness
                                'GHC.Generics.DecidedLazy)
                             (GHC.Generics.Rec0 Text)
                           GHC.Generics.:*: GHC.Generics.S1
                                              ('GHC.Generics.MetaSel
                                                 ('Just "resAge")
                                                 'GHC.Generics.NoSourceUnpackedness
                                                 'GHC.Generics.NoSourceStrictness
                                                 'GHC.Generics.DecidedLazy)
                                              (GHC.Generics.Rec0 Int32))
                          GHC.Generics.:*: (GHC.Generics.S1
                                              ('GHC.Generics.MetaSel
                                                 ('Just "resGender")
                                                 'GHC.Generics.NoSourceUnpackedness
                                                 'GHC.Generics.NoSourceStrictness
                                                 'GHC.Generics.DecidedLazy)
                                              (GHC.Generics.Rec0 Text)
                                            GHC.Generics.:*: GHC.Generics.S1
                                                               ('GHC.Generics.MetaSel
                                                                  ('Just "resLang")
                                                                  'GHC.Generics.NoSourceUnpackedness
                                                                  'GHC.Generics.NoSourceStrictness
                                                                  'GHC.Generics.DecidedLazy)
                                                               (GHC.Generics.Rec0 Text))))
        arising from a use of ‘GraphQL.Internal.Value.FromValue.$dmfromValue’
    • In the expression:
        GraphQL.Internal.Value.FromValue.$dmfromValue @Resource
      In an equation for ‘GraphQL.Internal.Value.FromValue.fromValue’:
          GraphQL.Internal.Value.FromValue.fromValue
            = GraphQL.Internal.Value.FromValue.$dmfromValue @Resource
      In the instance declaration for ‘FromValue Resource’
    |
359 | instance FromValue Resource
    |          ^^^^^^^^^^^^^^^^^^

Any idea what the problem might be?

@harendra-kumar
Copy link
Contributor Author

This is a serious impediment/bug in using this library, does anyone have any ideas about the problem or how to fix it?

dminuoso pushed a commit to dminuoso/graphql-api that referenced this issue Apr 6, 2018
@jamesdabbs
Copy link
Contributor

@harendra-kumar - while it looks like PR #178 has the "right" fix for this, in the mean time, you can always write your HasAnnotatedType instances by hand: see e.g. https://github.com/pi-base/server/blob/master/src/Graph/Class.hs#L166 / https://github.com/pi-base/server/blob/master/src/Graph/Class.hs#L246 for a reference.

@harendra-kumar
Copy link
Contributor Author

That's great, thanks @jamesdabbs !

@EdmundsEcho
Copy link

Gabriel Gonzalez had a similar problem with his optparse-generic package. He posted a detailed explanation of the problem that I thought might be helpful here.

-- START
Alright, I also fixed the issue of parsing 4 or more alternatives in c6e845c.

Here's a post-mortem explaining what went wrong for those who are curious. The correct version should have four instances:

-- Instance #1
instance
        (GenericParseRecord (f :+: g), GenericParseRecord (h :+: i))
    =>  GenericParseRecord ((f :+: g) :+: (h :+: i))

-- Instance #2
instance
        (Constructor c, GenericParseRecord f, GenericParseRecord (g :+: h))
    =>  GenericParseRecord (M1 C c f :+: (g :+: h))

-- Instance #3
instance
        (Constructor c, GenericParseRecord (f :+: g), GenericParseRecord h)
    =>  GenericParseRecord ((f :+: g) :+: M1 C c h)

-- Instance #4
instance
        (Constructor c1, Constructor c2, GenericParseRecord f1, GenericParseRecord f2)
    =>  GenericParseRecord (M1 C c1 f1 :+: M1 C c2 f2) where

The first problem was that instances 2 and 3 had an infinite loop, and they get triggered when you have three or more constructors. That's why you got an infinite loop when you had three alternatives

The second problem was that instance 1 was missing and was necessary for data types with 4+ alternatives. That is why the code failed to type-check for 4 or more alternatives.

-- END

Here is the link to the full post and code repo.

- E

@teh teh closed this as completed in #178 Aug 13, 2018
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

No branches or pull requests

3 participants