我正在学习Haskell,并且作为第一个挑战,我选择编写一种霍夫曼编码的实现,该算法几乎完成了,仅缺少将文件写入字节文件的部分。我需要做的是一种基于我构建的二进制字符串写入文件的方法。
例如,如果从txt
文件中读取以下字符串Hello
,在霍夫曼算法之后,我得到以下映射,该映射将符号映射为字符串的二进制数
[
("H": "110"),
("e": "111"),
("l": "0"),
("o": "10")
]
并且我需要替换读取的字符串中的字节并将该二进制数字的字节写为文件,我尝试使用ByteString包和writeFile函数,但是该函数将二进制数字写为纯文本而不是字节。
因此Hello
传递为110111010
,应将其作为字节写入文件。
您可以使用'0'
将'1'
和writeFile :: FilePath -> String -> IO ()
的字符串写入文件。例如:
writeFile :: FilePath -> String -> IO ()
您还可以将八位转换为main :: IO ()
main = writeFile "out.txt" "110111010"
,然后将Word8
写入具有ByteString
的WriteFile :: FilePath -> ByteString -> IO ()
的文件中:
WriteFile :: FilePath -> ByteString -> IO ()
您可以将Data.ByteString
module的列表转换为Data.ByteString
,但是这必须是8的倍数。例如,您可以用import Data.ByteString(writeFile, pack)
import Data.Word(Word8)
writeWord8s :: [Word8] -> IO ()
writeWord8s = writeFile "out.txt" . pack
(或Bool
或其他方式)“填充”它,但是它应该是8的倍数:
Word8
作为练习,我将输入映射到0
s和1
s的import Data.Bool(bool)
import Data.Bits((.|.), shiftL)
import Data.Word(Word8)
toWord8 :: [Bool] -> Word8
toWord8 = foldl ((. bool 0 1) . (.|.) . (`shiftL` 1)) 0
pack8pad0 :: [Bool] -> [Word8]
pack8pad0 [] = []
pack8pad0 xs
| null ys = [toWord8 (y ++ replicate (8 - length y) False)]
| otherwise = toWord8 y : pack8pad0 ys
where (y, ys) = splitAt 8 xs
。