从无限列表创建元组

fla*_*awr 3 haskell

在试图解决这个挑战时,我偶然发现了一些我无法解释的事情.

首先,我生成一个无限的素数列表,如下所示:

primes = [n|n<-[2..],product[1..n-1]`rem`n==n-1]
Run Code Online (Sandbox Code Playgroud)

这有推断类型,[Integer]因此Int溢出应该不是问题.

然后我尝试制作后续素数的2元组(目标:) [(2,3),(5,7),...].为此,我写了另一个函数:

listtotuples l=[ (l!!i, l!!(i+1) ) |i<-[0,2..]]
Run Code Online (Sandbox Code Playgroud)

奇怪的是,这个listtotuples函数似乎在例如上工作正常[0..],但它只是在我应用它时停止工作primes,输出只是(在中断之后)

[(2,3),(5,7),(11,13),(Interrupted.
Run Code Online (Sandbox Code Playgroud)

我不明白为什么会这样,有人能解释一下吗?

编辑:这不仅发生在尝试输出无限列表时,而且例如take 10 $ listtotuples primes在从上面加载带有两行的文件后在Prelude中使用.它确实卡在了完全相同的位置.

我使用Windows 7与GHCi 7.10.2.

EDIT2:我的文件的全部内容如下:

order p m=head[n-1|n<-[0..],mod m (p^n)>0] 
primes = [n|n<-[2..],product[1..n-1]`rem`n==n-1]
listtotuples l=[ (l!!i, l!!(i+1) ) |i<-[0,2..]]
p=listtotuples primes
f n=product[r^(order s n) * s^(order r n)|(r,s)<-take n p]
Run Code Online (Sandbox Code Playgroud)

一旦我评论/删除最后一行(该函数f,问题,但我仍然认为这是非常奇怪的,因为f没有被调用,并且没有与上述函数有任何共同点.问题,如果我take n p在函数中f替换[(2,3)]所有内容,问题就会消失.按定义工作.

Dan*_*ner 6

增加f强制你的素数类型Int,它在阶乘运算期间会溢出.推理是这样的:

  1. take :: Int -> [a] -> [a]
  2. f n,使用take n p力量n :: Int.
  3. 因为参数order必须具有相同的类型,即调用order r norder s n强制r, s :: Int.
  4. (r, s) <- take n p 军队 p :: [(Int, Int)]
  5. p = listtotuples primes 军队 primes :: [Int]

简单的修复包括打破上面的步骤2或3; 使用take (fromInteger n) p打破步骤2或order s (fromIntegral n)order r (fromIntegral n)断裂步骤3.

...现在您知道为什么添加顶级类型签名被认为是最佳实践.=)