UTNianos

Versión completa: [Haskell] Dudas con listas
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
hola, tengo dos dudas con el tema de listas:

la primera es: supongamos que tengo dos listas, como puedo hacer para saber si tienen elementos en comun ?

la segunda es: supongamos q tengo esta lista de tuplas : [("hola",1,2,3),("chau",4,5,6),("hasta luego",2,3,4)] y me piden por ejemplo que le sume 1 a la segunda componente de la tupla que contiene "hola","chau o "hasta luego" segun elija la persona que invoca la funcion, devolviendo la lista con esta modificacion. Como se puede hacer esto?
Para la primera vos queres saber solamente si tiene algun elemento en comun, o la lista de los que están en ambas. Si es el primer caso, podrías hacer:


tieneEnComun (x:xs) lista2 = elem x lista2 || tieneEnComun xs lista2


Para la segunda, tendrias una funcion que tiene 2 parametros, uno que es la palabra, y el otro que es tu lista. Deberias primero fijarte de los primeros elementos de tus tuplas cual coincide con tu palabra ingresada, y en esa tupla, sumarle 1.

Seria algo como


f palabra (x:xs) | palabra == primerElemento x = ((+1) . segundoElemento) x
| otherwise = f palabra xs

(22-04-2014 18:26)Diego Pedro escribió: [ -> ]Para la primera vos queres saber solamente si tiene algun elemento en comun, o la lista de los que están en ambas. Si es el primer caso, podrías hacer:


tieneEnComun (x:xs) lista2 = elem x lista2 || tieneEnComun xs lista2


Para la segunda, tendrias una funcion que tiene 2 parametros, uno que es la palabra, y el otro que es tu lista. Deberias primero fijarte de los primeros elementos de tus tuplas cual coincide con tu palabra ingresada, y en esa tupla, sumarle 1.

Seria algo como


f palabra (x:xs) | palabra == primerElemento x = ((+1) . segundoElemento) x
| otherwise = f palabra xs


Y si en el primer caso las listas son elementos de dos tuplas seria lo mismo?
Y en el segundo caso, en un ejercicio me dan una funcion en la q los parametros no contienen a la lista. Es algo raro, como si tuvieramos q comparar en la lista si se encuentra la palabra y modificar en la lista la tupla q la contiene
En el primer caso es lo mismo, fijate como está definida la función elem (en cuanto a tipos), y te vas a dar cuenta que pide comparar un elemento con una lista que sea de esos elementos, los cuales solo tienen la restriccion de ser comparables.

En el segundo caso, no entiendo bien que queres plantear, digamos si tu lista no es pasada como parametro tendría que venir de alguna otra funcón, sino deberias usar una expresión lambda para resolverlo.
(23-04-2014 06:04)Diego Pedro escribió: [ -> ]En el primer caso es lo mismo, fijate como está definida la función elem (en cuanto a tipos), y te vas a dar cuenta que pide comparar un elemento con una lista que sea de esos elementos, los cuales solo tienen la restriccion de ser comparables.

En el segundo caso, no entiendo bien que queres plantear, digamos si tu lista no es pasada como parametro tendría que venir de alguna otra funcón, sino deberias usar una expresión lambda para resolverlo.

la lista me la dan en el ejercicio digamos, y con esa funcion tendria q modificarla
La verdad necesitaria un ejemplo concreto para poder ayudarte, porque lo único que se me ocurre es lo que ya te dije que se hacía en tu consulta original.
ponele que tenés una lista que te dan en el enunciado:



naturales = [1..]


si vos tenés una función:

primerosQuinceDe lista = take 15 lista


si quisieras los primeros quince naturales, tenés que aplicar la lista que te dan:

primerosQuinceNaturales = primerosQuince naturales


Saludos!
adolfito: me temo que el ejemplo que te dio pedro no funciona (el segundo caso), mira


f palabra (x:xs)
| palabra == fst x = ((+1) . snd) x
| otherwise = f palabra xs


si vos corres eso:

ghci> f 3 [(3,1),(3,2)]
2

aca te tiro algo simple pero que lo podes adaptar a listas de lo que quieras

-- multiplicar por 2 los elementos iguales a 3


modificar' [] = []
modificar' (x:xs)
| x == 3 = (2*x) : modificar' xs
| otherwise = x : modificar' xs


ghci> modificar' [1,2,3,4,5]
[1,2,6,4,5]


otra forma seria esta


modificar'' xs = map (\x -> if x == 3 then 2*x else x) xs


el problema es que la catedra desaprueba el uso de if then else, por lo tanto ese ejemplo es solo a modo ilustrativo

volviendo a tu ejemplo, aca te dejo la resolucion


lista = [("hola",1,2,3),("chau",4,5,6),("hasta luego",2,3,4)]

fst4 (x,_,_,_) = x
sumar (a,b,c,d) = (a,b+1,c,d)

modificar _ [] = []
modificar clave (x:xs)
| clave == fst4 x = sumar x : modificar clave xs
| otherwise = x : modificar clave xs


ghci> modificar "hola" lista
[("hola",2,2,3),("chau",4,5,6),("hasta luego",2,3,4)]
ghci> modificar "chau" lista
[("hola",1,2,3),("chau",5,5,6),("hasta luego",2,3,4)]
ghci> modificar "hasta luego" lista
[("hola",1,2,3),("chau",4,5,6),("hasta luego",3,3,4)]
(22-04-2014 18:26)Diego Pedro escribió: [ -> ]Para la primera vos queres saber solamente si tiene algun elemento en comun, o la lista de los que están en ambas. Si es el primer caso, podrías hacer:


tieneEnComun (x:xs) lista2 = elem x lista2 || tieneEnComun xs lista2


deberias poner un caso base tambien porque la funcion esta es recursiva, sino le pones el caso base te tira un error de: 'non-exhaustive patterns...'

el caso base seria:

tieneEnComun [] lista = False

URLs de referencia