2012-03-17 19 views

Respuesta

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

(o, alternativamente, como en la solución de @ DanielWagner en el comentario anterior que funciona mejor, creo)

+8

Por qué 'concat' cuando ya estás en una lista por comprensión? 'enteros = 0: [y | x <- [1 ..], y <- [x, -x]] '. –

+0

@DanielWagner: Es cierto, me perdí esa solución :) –

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

No hay implementaciones estándar para mostrar todos los puntos en ℤ k . Ni siquiera para k == 1, realmente. Pero con cualquier enumeración de ℤ y un producto cartesiano de dos listas que generan cualquier par en un índice finito, incluso si las listas son infinitas (algunas implementaciones posibles here), puede hacer las suyas propias.

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]) 

Por supuesto, puede tomar el camino de la no-religioso, así:

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

Pero entonces no va a entender el verdadero significado de mu.

1

Hemos tenido muchas soluciones cortas. Aquí hay un sistemático, con tuplas de enteros también.

-- 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..] ] 

Un método mucho más simple que algunos que fueron publicadas aquí (aunque no es el orden usual).

+0

Eso no enumera todos los enteros, porque para 'n <0' no existe una' k' tal que 'n == l !! k'. – leftaroundabout

1

map (*) [1..] <*> [1,-1] que puede ser reescrito

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

o incluso

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

y para "el enrejado entero de la dimensión $ k $"? ¿Se puede hacer algo en este sentido allí? –

+0

como Q (k = 2)? No creo que funcione con aplicativo, pero debería funcionar con mónada o lista de comprensión. En ese caso, puede hacer cosas como [(p, q) | p <- [1 ..], q <- [-p..p]]. (Probablemente sea incorrecto, pero tienes la idea) ... – mb14

Cuestiones relacionadas