给定一个 8 位二进制文件,我想得到它的 char 表示。例如:
[0,1,1,0,0,0,0,1] 我相信它是“a”的二进制表示。
提前致谢!
import Data.Char
ord2chr :: [Int] -> Char
ord2chr = chr . foldl (\a b -> 2*a + b) 0
现在你可以试试
> ord2chr [0,1,1,0,0,0,0,1]
'a'
正如我在评论中建议的那样,这个问题可以一分为二。这是第一部分的建议,我为了 Haskellness 声明了一个Bit类型:
data Bit = Zero | One
fromBits :: (Integral a) => [Bit] -> a
fromBits bits = foldl f 0 (zip [0..] (reverse bits))
where
f x (_, Zero) = x
f x (n, One) = x + 2^n
那么这有什么作用呢?好吧,您的问题表明您的位列表首先具有最高有效位。我们将反向处理它,所以我们这样做reverse bits。然后,我们需要跟踪表示中两个不同元素的幂reverse bits,这就是ziping with[0..]所做的,产生 [(0, minimum-significant-bit), (1, second-least-significant bit), .. .]。最后foldl使用这个对列表,辅助函数f将 2 的适当幂添加到累加器。
我使用Integraltypeclass 不必选择整数类型。您可以在 8 位情况下使用Int,甚至。Word8对于更长的位列表,可以使用Integer任意精度(另请参见下面的 (*))。
对于第二部分,我们可以使用chr将 an 转换Int为Char,如果我们知道我们的位列表不是太大(*),fromIntegral可以将我们的Integral类型转换a为Int。
所以,你想要的可以写成:
convert :: [Bit] -> Char
convert = chr . fromIntegral . fromBits
在你的情况下,convert [Zero, One, One, Zero, Zero, Zero, Zero, One]是'a'。
(*) 当然,如果它们是,那么转换无论如何都没有明显的意义。但这里有一点我想带回家:我们把问题分成两部分,结果证明第一部分(处理位列表)可以用一种更通用的方式来解决环境。例如,fromBits (One:(replicate 100 Zero))是 2^100。