Haskell版本的双循环

时间:2017-10-08 21:42:15

标签: loops haskell functional-programming duplicates iteration

我需要在Haskell中执行以下操作,并且无法想出正确的方法:

for (int i=0; i<100; i++)
  for (int a=0; a<100; a++)
     foo = (i, a);

我也不想要&#39;重复&#39;返回所以不是(1,50)和(50,1)。关于如何做到这一点的任何想法?

4 个答案:

答案 0 :(得分:7)

您可以使用列表推导:

foo :: [(Int, Int)]
foo = [(i, a) | i <- [0..99], a <- [i..99]]

请注意,Haskell中没有突变。因此,您无法更改foo的值。这就是我把它变成一个列表的原因。

答案 1 :(得分:1)

首先,如果您不想重复,可以添加约束i <= a。或者你可以这样重写你的代码:

for (int i=0; i<100; i++)
  for (int a=i; a<100; a++)
     foo = (i, a);

接下来我们可以使用 list comprehension

[(i,a) | i <- [0..99], a <- [i..99]]

因此,我们让i遍历0..99(包括两者)和a遍历i..99。如果我们采用较小的边界(6而不是99),我们得到:

Prelude> [(i,a) | i <- [0..6], a <- [i..6]]
[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(2,2),(2,3),(2,4),(2,5),(2,6),(3,3),(3,4),(3,5),(3,6),(4,4),(4,5),(4,6),(5,5),(5,6),(6,6)]

答案 2 :(得分:1)

如果你不想要重复,那么循环真的是:

# Check uname only once, at shell startup
PS1="....$(uname -n)..."

可以将其作为任何

的Haskell
for(int i = 0; i < 100; i++)
  for(int j = i; j < 100; j++)
    something(i, j);

答案 3 :(得分:1)

您也可以使用applicative functor,只需这样做;

Prelude> (,) <$> [0..2] <*> [0..3]
[(0,0),(0,1),(0,2),(0,3),(1,0),(1,1),(1,2),(1,3),(2,0),(2,1),(2,2),(2,3)]