[英]How do I putStrLn a Data.ByteString.Lazy.Internal.ByteString?
[英]Data.ByteString.Lazy.Internal.ByteString to string?
嘗試編寫一個返回計算機外部IP地址的模塊。 使用Network.Wreq
get
函數,然后應用lense來獲取responseBody
,我最終得到的類型是Data.ByteString.Lazy.Internal.ByteString
。 因為我想過濾掉結果體的尾隨“\\ n”,我想隨后將它用於正則表達式。 問題:regex庫不接受看似非常具體的ByteString類型,我發現無法將其轉換為String
。
這是我到目前為止的微弱嘗試(不編譯)。
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.BytesString.Lazy
import Text.Regex.Posix
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
let body = r ^. responseBody
let addr = body =~ "[^\n]*\n"
return (addr)
所以我的問題顯然是:如何將有趣的特殊ByteString轉換為String
? 解釋我如何自己處理這樣的問題也是值得贊賞的。 我試圖使用unpack
和toString
但不知道要導入什么來獲取這些函數(如果它們存在)。
作為一個非常零星的haskell用戶,我也想知道是否有人可以向我展示定義這樣一個函數的慣用的haskell方式。 畢竟,我在這里展示的版本沒有考慮可能的運行時錯誤/異常。
簡短回答:使用Data.ByteString.Lazy.Char8中的unpack
更長的回答:
通常,當您想要將ByteString(任何種類)轉換為String或Text時,您必須指定編碼 - 例如UTF-8或Latin1等。
檢索HTML頁面時,您要使用的編碼可能會在Content-type標頭中或響應正文中顯示為<meta ...>
標記。
或者你可以猜測身體的編碼是什么。
在你的情況下,我認為你正在訪問像http://whatsmyip.org這樣的網站 ,你只需要解析你的IP地址。 因此,如果不檢查標題或瀏覽HTML,使用的安全編碼將是Latin1。
要通過編碼將ByteStrings轉換為Text,請查看Data.Text.Encoding中的函數
例如, decodeLatin1
函數。
我只是不明白為什么你堅持使用String
,當你已經有一個ByteString
,這是更快/更有效的實現。 導入regex
幾乎沒有任何好處 - 對於解析ip-address,我會使用attoparsec
,這對ByteString
很有用。
這是一個不使用正則表達式但返回一個字符串的版本 - 注意我沒有編譯它因為我現在沒有haskell設置。
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.ByteString.Lazy.Char8 as Char8
import Data.Char (isSpace)
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
return $ Char8.unpack $ trim (r ^. responseBody)
where trim = Char8.reverse . (Char8.dropWhile isSpace) . Char8.reverse . (Char8.dropWhile isSpace)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.