在 Haskell 中使用 Network.URL 库
Using Network.URL library in Haskell
读完 Yesod 书后,我对使用类型安全 URL 而不是原始字符串之类的想法深信不疑。我只是在尝试一些简单的获取请求,而不是使用完整的 yesod 库,但似乎很容易定义自定义 URL 数据类型派生显示,或者使用其他一些现有的最小 URL图书馆。
我在 Hoogle 上找到了这个:
https://hackage.haskell.org/package/url-2.1.3/docs/Network-URL.html
似乎它会做我想要的那种验证,所以像这样的错误:
myothervar = "kittens" -- oh no, I defined this for something else
parseRequest myothervar -- and called it from parseRequest!
会被编译器捕获,而
myurl = "http://example.com"
parseRequest myurl
...一定会成功的,太好了
ghci λ> import Network.URL
ghci λ> myurl = importURL "http://example.com"
文档提示我需要使用 importURL
ghci λ> :t myurl
myurl :: Maybe URL
太好了,我知道怎么去-Maybe
,我用Just
。
ghci λ> exportURL $ Just myurl
<interactive>:47:13: error:
• Couldn't match expected type ‘URL’
with actual type ‘Maybe (Maybe URL)’
• In the second argument of ‘($)’, namely ‘Just myurl’
In the expression: exportURL $ Just myurl
In an equation for ‘it’: it = exportURL $ Just myurl
ghci λ> Just (Just (URL {url_type = Absolute (Host {protocol = HTTP False, host = "example.com", port = Nothing}), url_path = "", url_params = []}))
好的,什么?那并没有删除我的 Just,它只是添加了另一个 Just。如何检索 parseRequest
将作为参数的字符串?
看来我确实需要通过某种方式导出回 String 来消除它:
ghci λ> import Network.HTTP.Conduit
ghci λ> parseRequest $ myurl
<interactive>:84:16: error:
• Couldn't match type ‘Maybe URL’ with ‘[Char]’
Expected type: String
Actual type: Maybe URL
这里有几件事值得讨论:
OK, what? That didn't remove my Just, it just added another Just. How can I retrieve the String that parseRequest will take as an argument?
记住类型为 Maybe URL
的东西是 Nothing
或 Just url
,其中 url :: URL
。你不能只 "extract" URL
的某些部分,因为 Maybe
的重点是 你可能根本没有 URL
!
How can I retrieve the String that parseRequest will take as an argument?
这是不必要的 - parseRequest
与 importURL
做同样的事情 - 它只是检查 URL 是否正确形成。唯一的区别是它通过使用 MonadThrow
中的 throwM
抛出错误来发出错误信号。此外,如果你想使用 http-conduit
,你无论如何都需要使用 parseRequest
来获得 Request
,所以 importURL
根本没有意义。
如果您担心格式错误 URL
,您可以确保将代码包装在 catch
.
中
import Network.Connection (TLSSettings (..))
import Network.HTTP.Conduit
main :: IO ()
main = catch (do
request <- parseRequest "https://github.com/"
let settings = mkManagerSettings (TLSSettingsSimple True False False) Nothing
manager <- newManager settings
res <- httpLbs request manager
print res)
(\e -> case e of
HttpExceptionRequest{} -> putStrLn "Http request failed"
InvalidUrlException{} -> putStrLn "Bad URL")
读完 Yesod 书后,我对使用类型安全 URL 而不是原始字符串之类的想法深信不疑。我只是在尝试一些简单的获取请求,而不是使用完整的 yesod 库,但似乎很容易定义自定义 URL 数据类型派生显示,或者使用其他一些现有的最小 URL图书馆。
我在 Hoogle 上找到了这个: https://hackage.haskell.org/package/url-2.1.3/docs/Network-URL.html
似乎它会做我想要的那种验证,所以像这样的错误:
myothervar = "kittens" -- oh no, I defined this for something else
parseRequest myothervar -- and called it from parseRequest!
会被编译器捕获,而
myurl = "http://example.com"
parseRequest myurl
...一定会成功的,太好了
ghci λ> import Network.URL
ghci λ> myurl = importURL "http://example.com"
文档提示我需要使用 importURL
ghci λ> :t myurl
myurl :: Maybe URL
太好了,我知道怎么去-Maybe
,我用Just
。
ghci λ> exportURL $ Just myurl
<interactive>:47:13: error:
• Couldn't match expected type ‘URL’
with actual type ‘Maybe (Maybe URL)’
• In the second argument of ‘($)’, namely ‘Just myurl’
In the expression: exportURL $ Just myurl
In an equation for ‘it’: it = exportURL $ Just myurl
ghci λ> Just (Just (URL {url_type = Absolute (Host {protocol = HTTP False, host = "example.com", port = Nothing}), url_path = "", url_params = []}))
好的,什么?那并没有删除我的 Just,它只是添加了另一个 Just。如何检索 parseRequest
将作为参数的字符串?
看来我确实需要通过某种方式导出回 String 来消除它:
ghci λ> import Network.HTTP.Conduit
ghci λ> parseRequest $ myurl
<interactive>:84:16: error:
• Couldn't match type ‘Maybe URL’ with ‘[Char]’
Expected type: String
Actual type: Maybe URL
这里有几件事值得讨论:
OK, what? That didn't remove my Just, it just added another Just. How can I retrieve the String that parseRequest will take as an argument?
记住类型为 Maybe URL
的东西是 Nothing
或 Just url
,其中 url :: URL
。你不能只 "extract" URL
的某些部分,因为 Maybe
的重点是 你可能根本没有 URL
!
How can I retrieve the String that parseRequest will take as an argument?
这是不必要的 - parseRequest
与 importURL
做同样的事情 - 它只是检查 URL 是否正确形成。唯一的区别是它通过使用 MonadThrow
中的 throwM
抛出错误来发出错误信号。此外,如果你想使用 http-conduit
,你无论如何都需要使用 parseRequest
来获得 Request
,所以 importURL
根本没有意义。
如果您担心格式错误 URL
,您可以确保将代码包装在 catch
.
import Network.Connection (TLSSettings (..))
import Network.HTTP.Conduit
main :: IO ()
main = catch (do
request <- parseRequest "https://github.com/"
let settings = mkManagerSettings (TLSSettingsSimple True False False) Nothing
manager <- newManager settings
res <- httpLbs request manager
print res)
(\e -> case e of
HttpExceptionRequest{} -> putStrLn "Http request failed"
InvalidUrlException{} -> putStrLn "Bad URL")