List 将0-s添加到列表中,直到它';s的长度是8英寸

List 将0-s添加到列表中,直到它';s的长度是8英寸,list,haskell,recursion,functional-programming,binary,List,Haskell,Recursion,Functional Programming,Binary,所以我必须将一个十进制数转换成二进制列表,如下所示:intToBitString 4=[1,0,0]。 我是这样做的: intToBitString n = reverse (helper n) helper 0 = [] helper n | n `mod` 2 == 1 = 1 : helper (n `div` 2) | n `mod` 2 == 0 = 0 : helper(n `div` 2) 但是我还要做一个名为intToByte的函数,它用0

所以我必须将一个十进制数转换成二进制列表,如下所示:intToBitString 4=[1,0,0]。 我是这样做的:

intToBitString n = reverse (helper n)

helper 0 = []
helper n 
        | n `mod` 2 == 1 = 1 : helper (n `div` 2) 
        | n `mod` 2 == 0 = 0 : helper(n `div` 2)
但是我还要做一个名为intToByte的函数,它用0-s填充列表,直到它的长度为8个元素。(因此将其设置为bytestring)如下所示: intToByte 7=[0,0,0,0,1,1,1]

我试过很多东西,但都不管用。我是一个初学者,所以我只知道上面显示的“if”循环和递归,但我不知道任何花哨的东西。我的一次尝试:

intToByte 0 = [0]

intToByte n
        | eight n == helper2 n = reverse (helper2 n)
        | otherwise = eight n

helper2 0 = []
helper2 n 
        | n `mod` 2 == 1 = 1 : helper2 (n `div` 2) 
        | n `mod` 2 == 0 = 0 : helper2 (n `div` 2)

eight n
        | length (helper2 n) < 8 = 0 : eight n
        | otherwise = helper2 n
intToByte 0=[0]
intToByte n
|八个n==helper2N=反向(helper2N)
|否则=8 n
helper2 0=[]
助手
|n`mod`2==1=1:helper2(n`div`2)
|n`mod`2==0=0:helper2(n`div`2)
八n
|长度(helper2N)<8=0:8N
|否则=helper2 n

我已经为此工作了这么多小时,以至于我被它弄糊涂了。但这是一项重要任务的一部分,因此我们非常感谢您的帮助

首先,您可以通过以下方法简化代码:

helper2 :: Integral i => i -> [i]
helper2 0 = []
helper2 n = r : helper2 q
    where (q,r) = quotRem n 2
第二,以上是一个例子。实际上,
7
表示为
[1,1,1]
,而
14
例如表示为
[0,1,1]
。如果我们想逆转这种情况,我们可以使用累加器:

helper2 :: Integral i => i -> [i]
helper2 = go []
    where go rs 0 = rs
          go rs n = go (r:rs) q
              where (q,r) = quotRem n 2
因此,这将
7
映射到
[1,1,1]
14
映射到
[1,1,0]
。但现在我们仍然需要添加前导零。例如,我们可以通过维护已添加到列表中的元素数量来实现:

eight :: Integral i => i -> [i]
eight = go [] 0
    where go rs l 0 = replicate (8-l) 0 ++ rs
          go rs l n = go (r:rs) (l+1) q
              where (q,r) = quotRem n 2
eight::Integral i=>i->[i]
八=去[]0
where go rs l 0=复制(8-l)0++rs
go rs l n=go(r:rs)(l+1)q

其中(q,r)=quotRem n2
一种方法是定义函数
,使
位k
将其参数转换为长度
k
的位字符串:

bits :: Int -> Int -> [Int]
bits 0 _n = []
bits k n | n < 0         = error "bits: negative"
         | n > 2 * m - 1 = error "bits: overflow"
         | otherwise     = let (i, j) = n `divMod` m in i : bits (k - 1) j
  where m = 2 ^ (k - 1)
这使得:

> eight 4
[0,0,0,0,0,1,0,0]

> eight 7
[0,0,0,0,0,1,1,1]

填充可以非常简单,只需计算要推送到列表中的额外元素的数量,然后使用Prelude中的函数
replicate
生成这些元素:

padLeft :: Int -> a -> [a] -> [a]
padLeft n x xs = replicate (n - length xs) x ++ xs
例如:

> padLeft 8 0 [1, 1, 0]
[0,0,0,0,0,1,1,0]

你的
m
计算效率相当低。为什么不传递
m
而不是
k
?此外,您还可以在包装器中处理错误条件。不考虑它们(尤其是溢出)错误也是合理的。
> padLeft 8 0 [1, 1, 0]
[0,0,0,0,0,1,1,0]