Requestable instance for DecodeJson
Closed this issue · 6 comments
Could types that already implement EncodeJson
implement Requestable
, and DecodeJson
implement Respondable
?
Something like this (quick sketch, might not compile):
instance respondableDecodeJson :: DecodeJson t => Respondable t where
fromResponse content = do
json <- fromResponse content
case decodeJson json of
Left err -> throwError (pure (JSONError err))
Right x -> pure x
responseType =
Tuple (Just applicationJSON) JSONResponse
Does this sound good? I could submit a PR.
OK, after having tried this out in affjax, it might not be realistic with the design of Respondable
. This instance would cause overlapping instances all over the place.
My original problem was orphan instances - I wanted to define an instance of Respondable
for any value that had an DecodeJson
instance. I'll try some newtype trickery to solve it instead.
It'll work out, closing this. :)
Yeah, unfortunately having instances just based on a constraint don't really work out as you found. If this is for hyper, perhaps it could provide those implementations above as helper functions for writing the instances though? As then users could just do something like:
instance respondableMyValue :: Respondable MyValue where
fromResponse = fromJsonResponse
responseType = jsonResponseType
Yes, it's for the Hyper client lib I'm working on. It turned out I didn't really need that general Respondable
instances for DecodeJson
constrained types. I could instead use Respondable and DecodeJson directly in a less general instance of my HasClient
class, and stitch it together like this:
instance hasClientsHandlerJson :: (DecodeJson b)
=> HasClients (Handler "GET" Json b) (Aff (ajax :: AJAX | e) b) where
getClients _ req = do
r <- affjax (toAffjaxRequest req)
case decodeJson r.response of
Left err -> throwError (error err)
Right x -> pure x
There will be more instances of HasClient (Handler ...)
for other content types (this is only Json
), but that's necessary anyway, I suspect. This example might not make sense to you out-of-context, sorry for that. I'll publish the source code soon. 😄
Ah cool, and yeah I see where you're coming from :) - as long as you know about the DecodeJson
instance you can apply it "manually" since there's a Respondable
for Json
.
Exactly! 👍