2012-03-17 64 views
8

所有整数的无限列表一个很好的方式,我写在Haskell下面的功能,因为它会列举每一个整数:什么是产生在Haskell

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

我不知道是否有更好的方法来做到这一点,它看起来有些复杂。

另外,我不知道是否有标准的实现列出维度$ k $的整数格中的所有元素。

回答

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

(或者,如@ DanielWagner在评论液低于工作得更好,我认为)

+8

为什么'当你在一个列表理解是已经concat'? '整数= 0:[y | x < - [1 ..],y < - [x,-x]]'。 – 2012-03-17 15:38:17

+0

@DanielWagner:没错,我错过了那个解决方案:) – 2012-03-17 15:49:02

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

有没有什么标准实现列出所有点ℤķ 。甚至不是对于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 
    -} 
6
import Control.Applicative 

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

当然你也可以采取非僧的路径,以及:

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

但你不会明白的mu真谛。

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 
0
[0..] ++ [ -x | x <- [1..] ] 

一个更简单的比其中一些被张贴在这里(虽然它不是通常的顺序)的方法。

+0

这并没有枚举所有的整数,因为对于'n <0',不存在'k'这样的'n == l !! k'。 – leftaroundabout 2014-06-24 14:43:43

1

map (*) [1..] <*> [1,-1]可以将它改写

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

甚至

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

和“维数$ k $的整数格”?在这方面可以做些什么吗?像Q(k = 2)那样的 – 2018-03-05 10:32:17

+0

?我认为它不适用于应用程序,但它应该适用于monad或list comprension。这种情况下,你可以做一些事情,如[(p,q)|) p < - [1 ..],q < - [-p..p]]。 (这可能是不正确的,但你有想法)... – mb14 2018-03-05 12:34:56

相关问题