给定一个 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
,这就是zip
ing with[0..]
所做的,产生 [(0, minimum-significant-bit), (1, second-least-significant bit), .. .]。最后foldl
使用这个对列表,辅助函数f
将 2 的适当幂添加到累加器。
我使用Integral
typeclass 不必选择整数类型。您可以在 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。