haskell - 如何使用 map 将自定义 Word8 应用于 Char 函数将 ByteString 转换为 Text?
问题描述
我正在尝试学习 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 来保存输出而不是字符串。
理想情况下:我想避免将 ByteString 转换为其他批发的东西,例如 [Word8],因为 - 最终 - 我需要学习如何使用它,而不是围绕它工作。
我的问题是我不能map
为我工作。B.map 和 T.map 都不起作用,因为它们需要一个 function ([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 中的每个字节并获取文本的“正确”方式是什么。
解决方案
你写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)
推荐阅读
- database - 如何处理多个公司使用的数据库,需要存储有关同一成员的特定和非特定数据?
- javascript - 根据速度和网格计算减速度
- c++ - 抽象函数(C++ 中的纯虚函数)可以阻止该类的实例化吗?它们是定义合约的一种方式吗?
- html - 为什么 Flexbox 不收缩到它的内容?
- javascript - 视频播放结束后添加事件
- javascript - 带有数据表js的ajax数据
- c# - 将多个 Excel 工作表读入单个制表符分隔的文本文件
- javascript - 有没有办法所有浏览器都支持在 javascript 中使用 xhr 删除用户会话
- javascript - 如何使用 javascript 在同一域上列出访问过的链接?
- android - Quasar - JDK 8('1.8.*')的 Cordova 要求检查失败