[英]How can I create such list in Haskell using list comprehension
所以我需要创建这样的列表
[2,4,5,8,9,10,11,16,17,18,19,20,21,22,23,32 ..]
模式如下:2 ^ 1,2 ^ 2,2 ^ 2 +1,2 ^ 3,2 ^ 3 +1,2 ^ 3 +2,2 ^ 3 +3 ..因此重复数( 2 ^ n +1,2 ^ n +2 ..每次也增加一倍)希望您明白这一点。 我可以使用Haskell中的函数创建这样的列表,但是我很想知道是否可以仅使用列表理解来实现
编辑:有人要求我演示解决此问题的功能方法。 这里是
rep _ 0 = []
rep a b = a : rep (a+1) (b-1)
createlist a = rep (2^(a+1)) (2^a) ++ createlist (a+1))
因此,如果我们说`take 50(createlist 0),结果将是
[2,4,5,8,9,10,11,16,17,18,19,20,21,22,23,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82]
因此,您始终需要使用初始参数0调用该函数。这确实是一个令人讨厌的解决方案,我想简化一下。
根据您的示例,列表如下所示:
2
4 5
8 9 10 11
16 17 18 19 20 21 22 23
32 33 34 35 36 37 38 39 40 41 ...
因此,对于从1到无穷大的每个i ,我们得出的元素范围为[2 i ,2 i +2 i-1 ) 。 我们可以将其直接写入列表理解中:
[ j | i <- [1..], j <- [2^i .. 2^i + 2^(i-1) - 1] ]
我们还可以让i
取2的幂,并在i
和div (3*i) 2
(不包括)之间产生元素,因此:
[ j | i <- iterate (2*) 2, j <- [i .. div (2*i) 3 - 1] ]
我们也可以将其转换为列表单子,例如:
iterate (*2) 2 >>= \i -> [i..div (3*i) 2 - 1]
或更多无积分(无积分):
import Control.Monad(ap)
iterate (*2) 2 >>= ap enumFromTo (pred . flip div 2 . (3 *))
可以尝试使用函数f ( i )编写列表的第 i 个项,其中i> = 0
整个无限列表可以表示为
L_0 ++ L_1 ++ L_2 ++ ...
其中每个L_n是形式的有限列表
L_n = [ 2^(n+1), 2^(n+1) + 1, ..., 2^(n+1) + (2^n - 1) ]
L_n的大小为2 ^ n,我们知道对于任何k,2 ^ 0 + 2 ^ 1 + ... + 2 ^ k = 2 ^(k + 1)-1(这是几何级数),所以如果要求找到无穷列表的第 i 个项位于哪个有限列表中,我们可以找到i> = 2 ^ m-1的最大整数m。完成后,我们可以放心地说第i 个项是在L_m。 我们还可以说, 第 i 个无限列表的术语是第(i - 2 ^ M + 1) 个 L_m的元件。
这使我们可以将最终序列(我们称为thatList)定义为
thatList :: [Int] thatList = [ fi | i <- [0..] ]
和
f :: Int -> Int fi = (2 ^ (m + 1)) + (i - (2 ^ m) + 1) where m = floor (logBase 2 (fromIntegral i + 1))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.