2010-03-21 26 views
8

Soy un novato absoluto en Haskell pero trato de entender cómo funciona.Haskell, lista del número natural

Quiero escribir mi propia lista perezosa de enteros como [1,2,3,4,5 ...].

Para la lista de los que han escrito

ones = 1 : ones 

y cuando intentó, funciona bien:

*Main> take 10 ones 
[1,1,1,1,1,1,1,1,1,1] 

¿Cómo puedo hacer lo mismo para el aumento de los números enteros?

He intentado esto pero de hecho falla:

int = 1 : head[ int + 1] 

Y después de eso ¿Cómo puedo hacer un método que multiplica dos corrientes? tales como:

mulstream s1 s2 = head[s1] * head[s2] : mulstream [tail s1] [tail s2] 
+1

Puede confundir la diferencia entre() y [], ya que su último ejemplo funciona (para listas infinitas) si reemplaza todo el [] por(). –

Respuesta

17

Las razones que int = 1 : head [ int + 1] no funciona son:

  • cabeza devuelve un solo elemento, pero el segundo argumento de : necesario que haya una lista.
  • int + 1 intenta agregar una lista y un número, que no es posible.

La manera más fácil de crear la lista contando desde 1 hasta infinito es [1..]

contar en pasos de 1 otros puede utilizar [firstElement, secondElement ..], por ejemplo, para crear una lista de todos los números enteros positivos impares: 1, 3 [..]

Para obtener infinitas listas de la forma [x, f x, f (f x), f (f (f x)),...] que puede utilizar iterate f x, por ejemplo, iterate (*2) 1 devolverá la lista [1, 2, 4, 16,...].

Para aplicar un pares operación en cada par de elementos de dos listas, utilice zipWith:

mulstream s1 s2 = zipWith (*) s1 s2 

Para hacer esta definición más concisa se puede utilizar la conexión de punto formulario:

mulstream = zipWith (*) 
11

para los números naturales tiene que usar el mapa:

num1 = 1 : map (+1) num1 

O comprensiones:

num2 = 1 : [x+1 | x <- num2] 

O, por supuesto:

num3 = [1..] 
+3

o también 'nat = 1: map succ nat' – sastanin

2

Hay sintaxis para esto en el langauge:

take 10 [1,2..] 

=> [1,2,3,4,5,6,7,8,9,10] 

Usted puede incluso hacer progresos diferentes:

take 10 [1,3..] 
=> [1,3,5,7,9,11,13,15,17,19] 
3

I' No estoy seguro de si esto es lo que estaba preguntando, pero me parece que usted quería para construir una lista de números naturales crecientes, sin depender de ninguna otra lista. Así, por esa razón, se pueden hacer cosas como

incr a = a : inrc (a+1) 
lst = inrc 1 

take 3 lst 
=> [1,2,3] 

que, técnicamente, se llama una función de acumulación (creo) y luego todo lo que hicimos es hacer un caso especial de ella fácilmente utilizables con 'LST'

puede volverse loco a partir de ahí, haciendo cosas como:

lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a) 

take 3 lst 
=> [1,2,3] 

y así sucesivamente, sin embargo, que probablemente se basa en algunas cosas que usted no ha aprendido todavía (en) - a juzgar por la OP - pero debería Todavía leo bastante fácilmente.

Oh, bien, y luego la multiplicación de la lista. Bueno, se puede utilizar zipWith (*) como se mencionó anteriormente, o se puede reinventar la rueda como esto (que es más divertido, confía en mí :)

lmul a b = (head a * head b) : lmul (tail a) (tail b) 
safemul a b = take (minimum [len a, len b]) (lmul a b) 

La razón de safemul, creo, se puede encontrar a cabo por experimentando con la función, pero tiene que ver con 'cola'. El problema es que no hay ningún caso para una lista vacía, listas que no coinciden, etc., por lo que tendrá que modificar varias definiciones (lmul _ [] = []) o usar guardias y/o dónde y así sucesivamente ... o seguir con zipWith :)

Cuestiones relacionadas