Skip to content
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

TH error in deriveArgDict #37

Open
dfordivam opened this issue Jan 27, 2021 · 2 comments
Open

TH error in deriveArgDict #37

dfordivam opened this issue Jan 27, 2021 · 2 comments

Comments

@dfordivam
Copy link

Here https://github.com/reflex-frp/reflex-gadt-api/blob/develop/Readme.md
If I change the definition of CatApi from

> data CatApi a where
>   CatApi_Identify :: Text -> CatApi (Either Text Token)
>   CatApi_DogApi :: Token -> DogApi a -> CatApi a

to

> data CatApi a where
>   CatApi_Identify :: Text -> CatApi (Either Text Token)
>   CatApi_DogApi :: Token -> DogApi a -> CatApi (Either Text a)

I get this error

Readme.lhs:99:3: error:
    The exact Name ‘a_Xhvt’ is not in scope
      Probable cause: you used a unique Template Haskell name (NameU),
      perhaps via newName, but did not bind it
      If that's it, then -ddump-splices might be useful
   |
99 | > deriveArgDict ''CatApi

Supporting an Either in this case is important for proper error handling of Token. Is the usage of deriveArgDict correct in this case? if yes, is this a bug?
if no, what is the proper way to achieve the Either like behavior?

@cgibbard
Copy link
Contributor

cgibbard commented Jan 12, 2023

It's tricky -- given an instance (c a), can we get hold of an instance c (Either Text a)? We'd need to know that in order to generate an instance of Has c (CatApi a). I think we're at a point now where we might be able to generate such an instance that uses QuantifiedConstraints, but it's not entirely trivial. You could perhaps write one by hand. (Sorry that I didn't notice this issue any sooner!)

@ymeister
Copy link

ymeister commented Jan 15, 2023

@cgibbard Thanks a lot!

Here's a working example, in case anyone faces the same problem:

data CatApi a where
  CatApi_Identify :: Text -> CatApi (Either Text Token)
  CatApi_DogApi :: AuthT DogApi a -> CatApi a

data AuthT :: (* -> *) -> * -> * where
  Auth :: Token -> f a -> AuthT f (Either Text a)

instance (forall a. c a => c (Either Text a), Has c f) => Has c (AuthT f) where
  argDict (Auth _ a) = case argDict a of
    (Dict :: Dict (c a)) -> Dict

instance ToJSON (AuthT DogApi a) where
  toJSON (Auth token a) = toJSON ("auth", (toJSON token, toJSON a))

instance FromJSON (Some DogApi) => FromJSON (Some (AuthT DogApi)) where
  parseJSON v = do
    (tag, body) <- parseJSON v
    case tag of
      "auth" -> do
        (token, Some a) <- parseJSON body
        pure $ Some $ Auth token a
      _ -> fail "fail auth"

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