I'm fairly new to Haskell, though not to programming, and I've been using the req library to perform HTTPS requests.
In order to retain some generality, there will be two types of request - one to create a document (via HTTP POST) and another to update a document (via HTTP PATCH, using a non-empty monoid in the updateMask
parameter).
I can infer the HTTP verb from whether updateMask == mempty
, but this won't compile because POST
and PATCH
are different data
declarations (although both are valid as the first parameter of req
because they are instances of HttpMethod
.
getSaveEventRequestResponse :: Text -> Option Https -> Document -> IO IgnoreResponse
getSaveEventRequestResponse authToken updateMask document =
runReq defaultHttpConfig $
req
(if updateMask == mempty
then POST
else PATCH)
(https "test.example.com" /: "api" /: "projects" /: "myproject")
(ReqBodyJson document)
ignoreResponse $
oAuth2Bearer (encodeUtf8 authToken) <> updateMask
If I swap out the if
conditional for either one of POST
or PATCH
the code compiles without error.
Is there a way to make the compiler allow this conditional response or do I have to duplicate this function, one using the POST
variant and another using the PATCH
?
Edit for the benefit of anyone who comes to this and tries to use the same code:
The condition I used (updateMask == mempty
) is not actually valid here, but that's not relevant to the question. The question stands if this condition is replaced by True
or False
.
Edit 2 regarding the linked question. While I now, having got the answer, see how closely linked it is, it relies on having already considered partial application. While the principle is the same, the introduction of partial application makes it difficult for a beginner with Haskell to apply the answer there to this context.
A possible solution is to use
(if updateMask == mempty then req POST else req PATCH) other args here
This is because
req :: (MonadHttp m, HttpMethod method, HttpBody body,
HttpResponse response,
HttpBodyAllowed (AllowsBody method) (ProvidesBody body))
=> method
-> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Now, AllowsBody POST
and AllowsBody PATCH
are equal, since both are defined as 'CanHaveBody
. Therefore, both req POST
and req PATCH
can share a common type:
req POST, req PATCH
:: (MonadHttp m, HttpBody body,
HttpResponse response,
HttpBodyAllowed 'CanHaveBody (ProvidesBody body))
=> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Having the same type, they can be used in the two branches of the same if then else
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With