繁体   English   中英

如何使用列表理解在Haskell中创建此类列表

[英]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的幂,并在idiv (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 *))

可以尝试使用函数fi )编写列表的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM