2012-03-17 99 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