[英]Split ByteString on a ByteString (instead of a Word8 or Char)
[英]How to convert ByteString to Text using map to apply a custom Word8 to Char function?
我正在嘗試學習 Haskell,我想我會嘗試復制 Linux 'xxd' 實用程序。 但是我被困在右側列(顯示 ASCII 或非打印字符的空白)。
提醒一下,典型的 xxd output 如下所示:
00000000: 4927 6d20 7472 7969 6e67 2074 6f20 6c65 I'm trying to le
00000010: 6172 6e20 4861 736b 656c 6c2e 2041 7320 arn Haskell. As
...
我還想利用 Unicode“控制圖片”塊來顯示控制代碼 0..31 的小符號,而不是點或占位符。 所以我有一個助手 function 將 Word8 轉換為 Char,同時用控制圖片塊中的等效字符替換控制字符。
http://www.unicode-symbol.com/block/Control_Pictures.html
約束:最終程序將從磁盤讀取文件,因此我希望讀取 ByteString 或惰性 ByteString。 另外我想使用 Data.Text 來保存 output 而不是字符串。
理想情況下:我想避免將 ByteString 轉換為其他批發的東西,例如 [Word8],因為 - 最終 - 我需要學習如何使用它,而不是圍繞它工作。
我的問題是我無法讓map
為我工作。 B.map 和 T.map 都不起作用,因為他們期望 function ([a] -> [a])
。 Prelude.map
看起來更有希望([a] -> [b])
,但我無法讓它與導入的類型一起使用。 所以我在定義我自己的 map 時有一個map
(只是為了嘗試找到可以工作的東西,然后我可以用內置的 ZC1C425268E68385D1AB5074C17A94F14TZ 代替,但是當我有更好的理解時)。
我擁有的非功能代碼如下
import qualified Data.ByteString as B
import qualified Data.Text as T
import Data.Word
import Data.Char
{- Make some normally undisplayable bytes into displayable chars -}
displayableChar :: Word8 -> Char
displayableChar w
| i < 32 = chr (0x2400 + i) -- 0x2420 control codes
| i < 33 = chr 0x2423 -- 0x2423 trough for space
| i < 127 = chr i
| i < 128 = chr 0x2421 -- 0x2421 del
| otherwise = ' '
where i = fromIntegral w
mymap :: (Word8 -> Char) -> B.ByteString -> [Char]
mymap f bstr
| bstr == B.empty = []
| otherwise = f x : map f xs
where
x = B.head bstr
xs = B.tail bstr
test_data = B.pack [1..250]
歡迎就將displayableChar
應用於 ByeString 中的每個字節並獲取 Text 的“正確”方式提出建議和建議。
您在 function 定義中寫了map
而不是mymap
:
mymap :: (Word8 -> Char) -> B.ByteString -> [Char]
mymap f bstr
| bstr == B.empty = []
| otherwise = f x : mymap f xs -- <- here
where
x = B.head bstr
xs = B.tail bstr
另一種方法是使用B.unwrap
來獲取Word8
的列表,這樣您就可以應用適用於列表的map
:
mymap :: (Word8 -> Char) -> ByteString -> [Char]
mymap f bs = map f (B.unwrap bs)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.