UTNianos

Versión completa: [Paradigmas] Orden superior - Haskell
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Tengo una duda muy sarpada con el orden superior. Quiero comparar si ambas condiciones devuelven true con la misma lista (ej: ("Leonardo",[4,6,7,8])), por lo tanto supongo que deberia usar filter 2 veces. Primero para el nombre y luego para ver si tiene mas de 3 notas.
Pregunto porque estoy hace bastante con esto y no me cierra del todo. Si uso any directamente, seria erroneo. Tambien se que puedo usar composicion de funciones, en teoria, pero no me sale =(

Alguna ayuda? Estoy hasta las bolas y no encuentre algun tutoria/libro que diga que se sarpe explicando.

Saludos

Cita:Dadas las siguientes definiciones:

find f lista = head (filter f lista)

--Este es un curso a modo de ejemplo para que lo usen en sus pruebas
cursoK1024 = [("Leonardo",[4,6,7,8]),("Raphael",[1]),("Donatello",[10,10,10]),("Michelangelo",[4,4])]

Se quiere
Dado el nombre de una persona y un curso saber si esa persona es un alumno regular de dicho curso.
Esto se da si se cumplen las siguientes condiciones:
que esa persona sea un alumno del curso y
que haya rendido al menos 3 parciales

Main> esRegularEn cursoK1024 "Shredder"
False

Main> esRegularEn cursoK1024 "Raphael"
False

Main> esRegularEn cursoK1024 "Leonardo"
True


find f lista = head (filter f lista)
curso = [("Leonardo",[4,6,7,8];),("Raphael",[1];),("Donatello",[10,10,10];),("Michelangelo",[4,4];)]

sacarnombre(nombre,_) = nombre
sacarnotas(_,notas) = notas
nombres = map sacarnombre
notas = map sacarnotas

rendido lis = filter ((>=3).length.sacarnotas) lis
esta lis nom = filter ((==nom).sacarnombre) lis

Mi haskell está un poco oxidado, pero:


esRegularEn c n = not (null (filter (\x -> length (snd x) <= 3 && (fst x) == n) c))


El filter


filter (\x -> length (snd x) <= 3 && (fst x) == n) c


te filtra todos los alumnos del curso c cuyo nombre sea n y su cantidad de notas sea <= 3. Podés probarlo por separado, reemplazando c por la lista del curso y n por un nombre de alumno.

El null recibe como parametro una lista y te dice si está vacía.
El not invierte el valor booleano, porque a vos te interesa saber si el alumno es regular, o sea, si la lista retornada por el filter tiene elementos.

Ojalá te sirva.

Saludos
Muchas gracias por tu tiempo, me sirvio para pensarlo de otra manera =D Pero tengo problema cuando recibo la lista vacia Confused Intente poner un not(null [])) pero es muy villa jaja Te dejo el codigo y en que consulta tendria error


curso = [("Leonardo",[4,6,7,8];),("Raphael",[1];),("Donatello",[10,10,10];),("Michelangelo",[4,4];)]
find f lista = head (filter f lista)
sacarnombre(nombre,_) = nombre
sacarnotas(_,notas) = notas
esRegularEn lista nombre = ((>=3).length.sacarnotas) (find ((nombre==).sacarnombre) lista)


Cita:esRegularEn curso "Shredder"
Program error: pattern match failure: head

Se me complica usar esa funcion porque me devuelve una lista si o si y me la pide para el tp Confused

Gracias =D
PRometo qu epronto viene el resaltado de codigo y el compilador en haskell
jaja, buenísimo.

@Niko: El problema es para aplicar head necesitas de una lista con elementos. Con esa implementación de la función find si le "metes" una lista vacía, o el filter te filtra todos los elementos de la lista, te va a dar ese error. No veo como escaparle.
Al final entregue el TP 'asi nomas' (Con el error del pattern match) y me lo dieron como aprobado jajaja. Posiblemente pueda utilizar listas por comprensión para solucionarlo, pero ya fue.

Pueden cerrar el topic
joya
Te lo dieron como aprobado, porque no importa si tira error (esta bien que falle cuando el find no encuentra un elemento) , ya que el manejo de errores no es parte de la materia.
Claro, mi idea seria fixearlo con una especie de IF. Pero es algo que no vimos todavia =P
No sé si te hacen usar si o si el find, pero se me ocurrió hacerlo así:


type Alumno = (String, [Integer])

esRegularEn :: [Alumno] -> String -> Bool
esRegularEn curso nombre = not $ null [al | al <- curso, (fst al) == nombre, length (snd al) >= 3]



La idea es buscar los alumnos que coincidan con ese nombre y ver si hubo al menos uno (si hay dos con el mismo nombre, uno desaprobado y uno aprobado va a devolver True, aunque se podría usar not $ null head [..] para fijarse nada mas el primero)
URLs de referencia