foldl :: (b -> a -> b) -> b -> [a] -> b
迭代地将一个以 a 开头的函数应用于sb
的列表,a
直到列表用完,然后返回结果。在这种情况下,我们a
的 s 可以是移位长度。所以1
, 2
, 4
. 我们可以用 构造这样的列表iterate :: (a -> a) -> a -> [a]
。的确:
powers2 = iterate (2*) 1
现在我们可以将该列表提供给foldl
. 执行的功能foldl
是\qi s -> xor qi (shiftL qi s)
。所以完整的功能是:
qn :: (Num a, Foldable t, Bits [a]) => Int -> r -> t Int -> [a]
qn n q = foldl (\qi s -> xor qi (shiftL qi s)) q $ take n $ iterate (2*) 1
因此,如果我们调用qn 3 q
我们将执行该函数三次q
,从而q2
在您的示例中获得。例如:
Prelude Data.Bits> qn 3 15
1285
自从:
q = 0000 0000 1111
shiftL q 1 = 0000 0001 1110
--------------
q0 = 0000 0001 0001
shiftL q0 2 = 0000 0100 0100
--------------
q1 = 0000 0101 0101
shiftL q1 4 = 0101 0101 0000
--------------
q2 = 0101 0000 0101
这是1285的二进制等价物。