2012-04-14 15 views
7

Tengo un poco de tarea que hacer y soy un novato completo de Haskell. La pregunta con la que estoy teniendo problemas es escribir una función que, cuando se da un número entero x y una lista de enteros, se aplica (x-y)*(x-y) a cada elemento en la lista y muestra la nueva lista, siendo y cada elemento de la lista de entrada.Usando el mapa para reemplazar elementos de una lista con (x-y) * (x-y), donde y es el elemento inicial

Tengo una idea muy aproximada tendré que usar la función map pero no estoy seguro de cómo hacerlo.

He estado buscando ejemplos para cuadrar cada elemento en una lista y entiendo cómo funciona eso, pero cómo implementaría el (x-y)*(x-y) con y siendo el elemento actual me desconcierta por completo.

squares :: [Int] -> [Int] 
squares (x:xs) = x * x : squares xs 
squares [] = [] 

la pregunta exacta que se han establecido es,

escribir una función rela que toma como argumentos un entero x y una lista de números enteros. Devuelve una lista similar, pero donde cada elemento y ha sido reemplazado por (x-y)*(x-y), p.

Main> rela 2 [3,5,7] 
[1,9,25] 

que han logrado conseguir que funcione después de leer algunos libros, pero el código que han hecho pierde el primer elemento de la lista. ¿Alguna explicación de por qué?

equation1 :: Int -> Int -> Int 
equation1 x y = (x-y)*(x-y) 
rela :: Int -> [Int] -> [Int] 
rela x [] =[] 
rela x (y:ys) = [ equation1 x y | y <- ys ] 

Respuesta

10

En primer lugar, probablemente deba crear una función separada que haga lo que desee.

p. Ej.

f x y = (x-y)*(x-y) 

Ahora, cada vez que se crea una función en Haskell con múltiples parámetros, que en realidad "curry" la función, lo que significa que se obtiene una nueva función al momento de solicitar el primer argumento de la misma.

Así, se llega a una nueva función al hacer esto

g = f 5 

La expresión f 5 es en realidad una función

y se puede aplicar una serie de 'g' y X será siempre '5 '

Así que si queremos crear una función que toma dos parámetros, '' e 'y' x, y aplica (x-y)*(x-y) a una lista donde y es el elemento actual, entonces todo lo que tenemos que hacer es lo siguiente:

f x y = (x-y)*(x-y) 
squareDifference x = map (f x) [1,2,3,4] 

que se puede utilizar llamando squareDifference 5 o cualquier otro número como argumento

Una versión más general permitiría a pasar en una lista, así

squareDifference x xs = map (f x) xs 

Qué le llame por haciendo squareDifference 3 [1,2,3]

+0

Gracias por responder tan rápidamente, pero después de unos pocos intentos, y aún estoy perplejo. estoy en el camino correcto al usar esto? rela :: (a -> [b]) -> [a] -> [b] fxy = (xy) * (xy) –

+0

@blaneclorley: Lo que quieres hacer es escribir una función 'map', que obtiene una función 'f :: a → b' como un parámetro y la aplica a todos los elementos de la lista, de modo que' map f [x₀, x₁, x₂, x₃ .. ≡] f≡ [f x₀, f x₁, f x₂ , f x₃ ..] '. Luego, simplemente crea una función parcialmente aplicada (ver arriba) y llama a 'map' con ella. La firma de tipo de 'rela' corresponde a' concatMap' y eso no es realmente lo que necesita en este caso. – Vitus

+0

Todavía perdido, si estoy siendo brutalmente honesto, necesito decirlo en términos simples, solo he hecho un poco de programación y eso fue hace años. Pensé que el mapa estaba predefinido?si tengo que crear mi propia función de mapa, ¿cómo haré que obtenga la función? –

10

¿entiendes las funciones lambda?

map (\val -> the function) xs 

es lo que necesita.

currar es aún mejor, pero no tan simple.

edición:

más conceptual ...

mapa itera una lista aplicando una función.

map (+ 3) xs 

utiliza la técnica currificación mencionado anteriormente. también podría:

map (\x -> x + 3) xs 

para lograr lo mismo.

+0

siento que no tiene sentido para mí, he estado tratando de encontrar la manera de escribir una función llamada rela que toma como argumentos una entero xy una lista de enteros. Devuelve una lista similar, pero donde cada elemento y ha sido reemplazado por (xy) * (xy), y cuando rela 2 [3,5,7] se ingresa en el terminal, se devuelve la nueva lista [1,9,25] . Me acerqué usando la ayuda que se proporciona arriba, pero no puedo hacer que funcione, ¿me pueden ayudar? –

+0

esperar en la terminal o en ghci? – bbrittain

+0

utilizando abrazos en el terminal –

2

ejemplo simple:

rela :: Int -> [Int] -> [Int] 
rela x = map (\y -> (x-y)*(x-y)) 

O puede ser que usted quiere cualquier perversiones? -) Aquí está con aplicativos:

import Control.Applicative 
rela :: Int -> [Int] -> [Int] 
rela x = map $ (*) <$> (x-) <*> (x-) 
0

Hola supongo que quiere decir esto:

Prelude> let rela n = map (\ x -> (x - n)^2) 
Prelude> rela 2 [3,5,7] 
[1,9,25] 
Cuestiones relacionadas