在Haskell中生成所有整数的无限列表的好方法是什么?

时间:2012-03-17 12:14:57

标签: haskell

我在haskell中编写了以下函数,因为它将枚举每个整数:

integers = (0:)$ concat $ zipWith (\x y -> [x,y]) [1..] (map negate [1..])

我想知道是否有更好的方法来做到这一点,看起来确实有点过于复杂。

另外,我想知道是否有标准实现来列出维度$ k $。

的整数点阵中的所有元素

6 个答案:

答案 0 :(得分:17)

integers = 0 : concat [[x,(-x)] | x <- [1..]]

(或者,正如@ DanielWagner在下面评论中的解决方案中我认为的更好)

答案 1 :(得分:6)

import Control.Applicative

integers = 0 : zipWith (*) ([1..] <* "mu") (cycle [1,-1])

当然,你也可以走非僧人的道路:

integers = 0 : [y | x <- [1..], y <- [x,-x]]

但是你不会理解mu的真正含义。

答案 2 :(得分:3)

map fun [0 .. ]
  where
    fun n
      | even n = n `quot` 2
      | otherwise = (1 - n) `quot` 2

没有任何标准实现可以列出ℤ k 中的所有点。甚至不是k == 1,真的。但是,任何枚举的ℤ和两个列表的笛卡尔积,即使列表是无限的(某些可能的实现here),也会以有限的索引输出任何对,你可以自己滚动。

integers :: [Integer]
integers = -- whatever is your favourite implementation

-- get all pairs at finite index, even for infinite input lists
-- 
cartesian :: [a] -> [b] -> [(a,b)]
cartesian xs ys = ???

-- enumDim k enumerates the points in ℤ^k, to avoid type problems, the points
-- are represented as lists of coordinates, not tuples
enumDim :: Int -> [[Integer]]
enumDim k
  | k < 0     = error "Can't handle negative dimensions"
  | k == 0    = [[]]
  | otherwise = map (uncurry (:)) $ cartesian integers (enumDim (k-1))
  -- alternative:
  {-
  | k == 1    = map return integers
  | otherwise = map (uncurry (++)) $ cartesian (enumDim h) (enumDim (k-h))
    where
      h = k `quot` 2
  -}

答案 3 :(得分:1)

我们有很多解决方案。这是一个系统的,也有整数元组。

-- interleave lists
interleave :: [a] -> [a] -> [a]
interleave [] ys = ys
interleave xs [] = xs
interleave (x:xs) (y:ys) = x : y : interleave xs ys

-- positive integers
positiveIntegers = 1 : [k + 1 | k <- positiveIntegers]

-- negative integers
negativeIntegers = map negate positiveIntegers

-- integers
integers = 0 : interleave positiveIntegers negativeIntegers

-- enumeration of the cartesian product of two lists
prod :: [a] -> [b] -> [(a,b)]
prod [] ys = []
prod xs [] = []
prod (x:xs) (y:ys) = (x,y) : interleave (interleave xys yxs) (prod xs ys)
    where xys = map (\y -> (x,y)) ys
          yxs = map (\x -> (x,y)) xs

-- the k-fold power of a list
power :: Int -> [a] -> [[a]]
power 0 xs = [[]]
power k xs = map (\(y,ys) -> y:ys) (prod xs (power (k-1) xs))

-- all quadruples of integers
integerQuadruples = power 4 integers

-- the millionth quadruple is [62501,0,0,1]
something = integerQuadruples !! 1000000

答案 4 :(得分:1)

map (*) [1..] <*> [1,-1]可以重写

(*) <$> [1..] <*> [1,-1]` 

甚至

liftA2 (*) [1..] [-1,1]

答案 5 :(得分:0)

[0..] ++ [ -x | x <- [1..] ]

比这里张贴的更简单的方法(虽然这不是通常的顺序)。