我需要在Haskell中执行以下操作,并且无法想出正确的方法:
for (int i=0; i<100; i++)
for (int a=0; a<100; a++)
foo = (i, a);
我也不想要&#39;重复&#39;返回所以不是(1,50)和(50,1)。关于如何做到这一点的任何想法?
答案 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)..."
可以将其作为任何
的Haskellfor(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)]