【问题标题】:How to convert ByteString to Text using map to apply a custom Word8 to Char function?如何使用 map 将自定义 Word8 应用于 Char 函数将 ByteString 转换为 Text?
【发布时间】:2021-04-14 20:31:52
【问题描述】:

我正在尝试学习 Haskell,我想我会尝试复制 Linux 'xxd' 实用程序。但是我被困在右侧列(显示 ASCII 或非打印字符的空白)。

提醒一下,典型的 xxd 输出如下所示:

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 的小符号,而不是点或占位符。所以我有一个辅助函数,可以将 Word8 转换为 Char,同时用控制图片块中的等效字符替换控制字符。

http://www.unicode-symbol.com/block/Control_Pictures.html

约束:最终程序将从磁盘读取文件,因此我希望读取 ByteString 或惰性 ByteString。我也想使用 Data.Text 来保存输出而不是 String。

理想情况下:我想避免将 ByteString 转换为其他批发形式,例如[Word8] 因为 - 最终 - 我需要学习如何使用它,而不是绕过它。

我的问题是我无法让map 为我工作。 B.map 和 T.map 都不起作用,因为它们需要一个函数 ([a] -> [a])Prelude.map 看起来更有希望,因为它期望 ([a] -> [b]) 但我无法让它与导入的类型一起使用。所以我尝试定义自己的map(只是为了尝试找到可以工作的东西,然后当我有更好的理解时,我可以用内置函数替换)但这也不起作用。

我的非功能代码如下

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 中的每个字节并输出文本的“正确”方式。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    您在函数定义中写了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)
    

    【讨论】:

    • 啊啊啊啊!我离得太近了,我简直不敢相信!谢谢。
    猜你喜欢
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 2017-02-07
    • 1970-01-01
    • 2019-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多