Donar $20 Donar $50 Donar $100 Donar mensualmente
 


Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Buscar en el tema
Consulta ejercicio 1b parcial funcional 18/09/2010
Autor Mensaje
gan Sin conexión
Profesor del Modulo A
:ö:
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 286
Agradecimientos dados: 87
Agradecimientos: 143 en 47 posts
Registro en: Apr 2011
Mensaje: #1
Consulta ejercicio 1b parcial funcional 18/09/2010 Parciales y 1 más Paradigmas de Programación
Me trabe con esto..

1b) Conocer el monto de facturación de un paciente, o sea, lo que el dentista le facturó a la obra social por los servicios que le dió:

*Main> montoFacturacionDe "karl"
150


Consejo: usar las funciones del ej 1a y la que se muestra a continuación:


cuantoCuesta obraSocial servicio ((obraSocial1, servicio1, costo):servicios) | obraSocial == obraSocial1 && servicio == servicio1 = costo
| otherwise = cuantoCuesta obraSocial servicio servicios


Y en 1a) definí esta función datosDe:


esElPaciente paciente (nombre,_,_,_) = paciente == nombre

datosDe paciente = (head . filter (esElPaciente paciente)) pacientes


También se cuenta con los sigs. datos y funciones:


pacientes = [("karl", (10,10,1993), "OSDE", ["Conducto", "Puente"]), ("achi", (18,11,1987), "Swiss Med", []), ("mike", (12,04,1978), "OSDE", ["Limpieza"])]

precios = [("OSDE", "Conducto", 100), ("OSDE", "Puente", 50), ("OSDE", "Limpieza", 50), ("Swiss Med", "Conducto", 30), ("Swiss Med", "Puente", 50), ("Swiss Med", "Limpieza", 50)]

paciente (p,_,_,_) = p
fechaNac (_,f,_,_) = f
obraSocial (_,_,os,_) = os
servicios (_,_,_,s) = s
anio (_,_,a) = a


Luego de decir todo esto, lo que hice hasta ahora fue:


obrSocPaciente = obraSocial . datosDe

servPaciente = servicios . datosDe

montoFacturacionDe paciente = sum (map (cuantoCuesta (obrSocPaciente paciente) XXX YYY) (servPaciente paciente))


Mi problema es: como defino los argumentos de cuantoCuesta adentro del map? Ahi donde puse xxx yyy

Espero se entienda, gracias.
(Este mensaje fue modificado por última vez en: 22-04-2014 08:08 por gan.)
22-04-2014 07:48
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Ichiluk Sin conexión
Campeon del cubo Rubik
Metametaprogramando.
****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 134
Agradecimientos dados: 5
Agradecimientos: 21 en 18 posts
Registro en: Apr 2008
Mensaje: #2
RE: Consulta ejercicio 1b parcial funcional 18/09/2010
Me parece que te faltan abstracciones. No termino de entender del todo tu función, pero me parece que te estás perdidendo con las funciones que necesitás y los parámetros.
Es importante destacar que la lista es de servicios y eso es lo que le está llegando al map, pero no es lo último que le tenés que aplicar a la función cuantoCuesta. Para eso necesitamos delegarlo en otra función, o bien usar una lambda:


montoFacturacionDe nombre = sum (map (\servicio -> cuantoCuesta (obraSocialDePacienteLlamado nombre) servicio precios) serviciosDePacienteLlamado nombre)


---------------------------------------------------------

Voy a hacer una resolución alternativa, con mas delegación y contándola medio apb así si hay gente que está medio perdida nos sigue, si no te interesa el razonamiento que estoy haciendo podés salteártelo e ir derecho a las definiciones de código =)

De entrada, lo que te piden es saber cuánto le facturó el dentista a la obra social por los servicios que se le realizaron.
Es decir, sabemos que el montoDeFacturacion de una persona lo sacás obteniendo los servicios de la persona y viendo cuanto le cuestan todos estos servicios a la obra social. Entonces lo podrías definir algo así como


montoDeFacturacionDe unNombre = cuantoLeCuestanA (servicios (personaLlamada unNombre)) (obraSocial (personaLlamada unNombre))


personaLlamada es parecida a datosDe que definiste vos, pero no me gustó el nombre que elegiste. No se si el enunciado lo pide así, pero me parece que cuando digo "personaLlamada" recibo un nombre y me devuelve la persona (la 4-upla).
Entonces delegás todo en una función que recibe una lista de servicios y una obra social y te dice cuanto le cuestan. Veamos como hacemos eso.

Hay varias formas de encarar esto. Podemos foldearlo todo a un valor, o hacerlo en funciones separadas. Vamos con la 2da, que me parece mas simple para verlo.


cuantoLeCuestanA servicios obraSocial = sum (preciosDeServiciosSegun servicios obraSocial)


Bien fácil. Delegamos en una lista que veremos como la obtenemos mas adelante.

Ahora, preciosDeServiciosSegun recibe unos servicios, una obra social y devuelve una lista con los precios de cada servicio en la lista que recibe.


preciosDeServiciosSegun servicios obraSocial = map (precioPara obraSocial) servicios


acá hay algo medio tricky: el map recibe como 2do parámetro una función. entonces, precioPara está parcialmente aplicada. Como primer parámetro recibe una obra social, y como segundo parámetro un servicio (la función que recibe el map como 1er argumento debe recibir un elemento de la lista que recibe el map como 2do argumento). Hagamos, entonces, esta función que nos falta.

Para saber el precio de cuánto le sale a una obra social un determinado servicio, probablemente nos convenga usar la función que ya nos dieron, que sin mirar la definición horrible que tiene, vemos que se llama "cuantoCuesta" y recibe una obra social, un servicio y una lista de precios, siendo el precio una 3-upla de la forma (ObraSocial, Servicio, Costo). Podemos definir nuestra función como


precioPara unaObraSocial unServicio = cuantoCuesta unaObraSocial unServicio precios


precios es la función constante que nos viene como dato.

Entonces ya tenemos todo lo que necesitábamos =)

---------------------------------------------------------

Bonus: Definamos cuantoLeCuestanA con un fold =)


cuantoLeCuestanA' servicios obraSocial = foldl (\acum servicio -> acum + precioPara obraSocial servicio) 0 servicios

El foldl recibe una función de 2 parámetros, un valor inicial y una lista. La función debe retornar del mismo tipo que el valor inicial, y recibe como primer parámetro algo del tipo del valor inicial y como 2do parámetro algo del tipo de la lista. El 0 es el elemento neutro para la suma, y como quiero hacer una sumatoria, le plancho ese como valor incial =)

---------------------------------------------------------

Espero haya quedado claro, cualquier duda me preguntan =)
(Este mensaje fue modificado por última vez en: 22-04-2014 16:58 por Ichiluk.)
22-04-2014 16:58
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] Ichiluk recibio 1 Gracias por este post
gan (22-04-2014)
gan Sin conexión
Profesor del Modulo A
:ö:
*****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 286
Agradecimientos dados: 87
Agradecimientos: 143 en 47 posts
Registro en: Apr 2011
Mensaje: #3
RE: Consulta ejercicio 1b parcial funcional 18/09/2010
Muy copada tu explicación. Hubo 2 cosas que no me quedaron claras:

1) Cuando haces montoFacturaciónDe basándote en mi función, de dónde se recibe el dato de servicio en la expresión lambda? (este tema todavía no lo estudié demasiado)

2) No termino de entender la parte "tricky", es decir, cómo funciona preciosDeServiciosSegun.
Cómo puede ser que precioPara recibe 1 servicio y al map le pasa una lista de dichos servicios y funciona? No son diferentes tipos?

Gracias.

edit. resumido, definí la función asi, lo más parecido a mi idea original:


montoFacturacionDe nombre = sum (map (precioPara (obrSocPaciente nombre)) (servPaciente nombre))


El problema lo tenía en la cant. de argumentos que recibe cuantoCuesta, asique use la función que definió Ichiluk para cambiar eso.
(Este mensaje fue modificado por última vez en: 22-04-2014 23:13 por gan.)
22-04-2014 23:01
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
Ichiluk Sin conexión
Campeon del cubo Rubik
Metametaprogramando.
****

Ing. en Sistemas
Facultad Regional Buenos Aires

Mensajes: 134
Agradecimientos dados: 5
Agradecimientos: 21 en 18 posts
Registro en: Apr 2008
Mensaje: #4
RE: Consulta ejercicio 1b parcial funcional 18/09/2010
(22-04-2014 23:01)gan escribió:  Muy copada tu explicación. Hubo 2 cosas que no me quedaron claras:

1) Cuando haces montoFacturaciónDe basándote en mi función, de dónde se recibe el dato de servicio en la expresión lambda? (este tema todavía no lo estudié demasiado)
De serviciosDePacienteLlamado nombre (Me faltaron paréntesis para que compile, pero la idea es esa). Esto devuelve una lista de servicios. Y la función que recibe el map como parámetro trabaja con un servicio. Entonces no debería de haber problemas.

(22-04-2014 23:01)gan escribió:  2) No termino de entender la parte "tricky", es decir, cómo funciona preciosDeServiciosSegun.
Cómo puede ser que precioPara recibe 1 servicio y al map le pasa una lista de dichos servicios y funciona? No son diferentes tipos?

Definición:

preciosDeServiciosSegun servicios obraSocial = map (precioPara obraSocial) servicios


Uno de los ayudantes que tuve cuando cursé paradigmas decía que haskell es medio puto porque se la pasa viendo los tipos de todo =P
Entonces podemos analizar los tipos de la función para ayudarnos a entender:

map :: (a -> b) -> [a] -> [b]


recibe una función cuyo argumento es algo del tipo de los elementos de la lista (no del tipo lista, sino del tipo de lo que la lista tiene adentro) y una lista de elementos, y devuelve otra lista.

Pensemos en el tipo de precioPara:

precioPara :: String -> String -> Num

que, a efectos del dominio, podemos transformar en

precioPara :: ObraSocial -> Servicio -> Num

recibe 2 parámetros. La el map espera una función que reciba sólo un parámetro. Entonces aplicamos parcialmente precioPara, así tenemos una nueva función:

(precioPara unaObraSocial) :: Servicio -> Num

(esto claramente no funciona en el compilador, pero imaginemos por un momento que estamos en el medio de la ejecución del programa)

Esto es lo que estamos buscando para el map que necesitamos =)

El tipo de la función preciosDeServiciosSegun

preciosDeServiciosSegun :: [Servicio] -> ObraSocial -> [Num]


nuestro map aplicado sería


mapEnnuestroContexto :: (Servicio -> Num) -> [Servicio] -> [Num]


Entonces no tenemos drama con los tipos.

Me explico? =)
24-04-2014 15:01
Encuentra todos sus mensajes Agregar agradecimiento Cita este mensaje en tu respuesta
[-] Ichiluk recibio 1 Gracias por este post
gan (07-05-2014)
Buscar en el tema
Enviar respuesta 




Usuario(s) navegando en este tema: 1 invitado(s)



    This forum uses Lukasz Tkacz MyBB addons.