sam*_*dy1 5 haskell types typeclass haskell-req
我对 Haskell 还是很陌生,虽然不是编程,我一直在使用req 库来执行 HTTPS 请求。
为了保留一些通用性,将有两种类型的请求 - 一种用于创建文档(通过 HTTP POST),另一种用于更新文档(通过 HTTP PATCH,在updateMask参数中使用非空的 monoid )。
我可以从 if 推断出 HTTP 动词updateMask == mempty,但这不会编译,因为POST和PATCH是不同的data声明(尽管两者都作为 of 的第一个参数有效,req因为它们是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
Run Code Online (Sandbox Code Playgroud)
如果我换出if其中之一的条件POST或PATCH代码编译没有错误。
有没有办法让编译器允许这个条件响应,或者我是否必须复制这个函数,一个使用POST变体,另一个使用PATCH?
为了任何来到这里并尝试使用相同代码的人的利益而进行编辑:
我使用的条件 ( updateMask == mempty) 在这里实际上无效,但这与问题无关。问题是这个条件是否被替换为True或False。
编辑 2关于链接问题。虽然我现在得到了答案,看看它有多么紧密的联系,但它依赖于已经考虑过部分应用。虽然原理是一样的,但部分应用的引入使得 Haskell 初学者很难将那里的答案应用到这个上下文中。
一个可能的解决方案是使用
(if updateMask == mempty then req POST else req PATCH) other args here
Run Code Online (Sandbox Code Playgroud)
这是因为
req :: (MonadHttp m, HttpMethod method, HttpBody body,
HttpResponse response,
HttpBodyAllowed (AllowsBody method) (ProvidesBody body))
=> method
-> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Run Code Online (Sandbox Code Playgroud)
现在,AllowsBody POST和AllowsBody PATCH是相等的,因为两者都被定义为'CanHaveBody。因此,req POST和req PATCH可以共享一个公共类型:
req POST, req PATCH
:: (MonadHttp m, HttpBody body,
HttpResponse response,
HttpBodyAllowed 'CanHaveBody (ProvidesBody body))
=> Url scheme
-> body
-> Proxy response
-> Option scheme
-> m response
Run Code Online (Sandbox Code Playgroud)
具有相同的类型,它们可以在同一个if then else.