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