haskell-graphql / graphql-api

Write type-safe GraphQL services in Haskell
BSD 3-Clause "New" or "Revised" License
406 stars 35 forks source link

Writing Type signatures and cryptic type errors #175

Open harendra-kumar opened 6 years ago

harendra-kumar commented 6 years ago

I am finding the type errors very cryptic and hard to fix, though once you get the hang of it, it becomes better. But when you are starting out with this library its a big pain.

Also, can there be a better way of writing type signatures, e.g. GHC prints this for one case:

    Top-level binding with no type signature:
      buildResource :: (Monad m7, Monad m6, Monad m5, Monad m4, Monad m3,
                        Monad m2, Monad m1) =>
                       ResourceTable
                       -> m1 (m2 (Maybe (m2 Int32))
                              :<> (m3 (Maybe (m3 Text))
                                   :<> m7 (Maybe
                                             (m4 (m5 [m5 (m5 Text :<> m5 [m5 Text])]
                                                  :<> m6 [m6 Text])))))
teh commented 6 years ago

@harendra-kumar For the specific error you mention there aren't any easy fixes. We're trying to constrain the type machinery as much as possible where we can but we don't have any way to hook into GHCs type inference messages to rewrite them to graphql-api terms.

If you have any ideas for how to fix PRs are more than welcome! Otherwise I think I'll close this as "not possible" if that's OK with you?

harendra-kumar commented 6 years ago

Actually, I just figured what I was looking for, it is already there. The above type signature can be written nicely using Handler e.g.:

type GetResource = Object "GetResource" '[]
  '[ Field "age" (Maybe Int32)
   , Field "gender" (Maybe Text)
   , Field "_acl" (Maybe GQLACLInfo)
   ]

buildResource :: Monad m => ResourceTable -> Handler m GetResource
buildResource rsrc = return
    (   getResInt32 (resourceTableResAge rsrc)
    :<> getResText (resourceTableResGender rsrc)
    :<> getResAcl (resourceTableRecordACL rsrc)
    )

When I omit the the buildResource signature in the above snippet I get the complex GHC generated type signature warning that I pasted when opening the issue. But I figure this is the way to write the signature. Maybe you can put this somewhere in the docs to make it clear how to write signatures, and what you need to do if you get that kind of warnings.