visual studio primera minusculas mayusculas mayuscula listas letra ejercicios ejemplos convertir list haskell map filter toupper

studio - Haskell: escribe en mayúsculas todas las letras en una lista[String] con toUpper



string en haskell (3)

Sé que toUpper en esta línea de código obtiene una lista como valor y, por lo tanto, no puede funcionar, pero sabe cómo bajar un nivel en la lista y aplicar el mapa a Superior.

Use (map . map) lugar de map .

nb (map . map) toUpper es lo mismo que map (map toUpper) como lo sugieren las otras respuestas. Lo menciono porque, personalmente, me parece más claro: parece que va a bajar dos niveles para aplicar a toUpper . (Puede que no esté familiarizado con el operador de composición de funciones (.) , Búsquelo o pregúntele si es necesario).

Otras funciones con un tipo similar ( (a -> b) -> something a -> something b ), como fmap , Data.Map.map , first y second , se pueden combinar entre sí y con el map de forma similar .

Tal vez no encuentre (map . map) toUpper más claro que el map (map toUpper) ; lo suficientemente justo.

Tengo una lista [String] la tarea para eliminar esos elementos en la lista, que tienen "q" o "p" y luego escribe en mayúscula todas las letras de la lista con toUpper.

Lo que intenté todavía es como sigue:

delAndUpper :: [String] -> [String] delAndUpper myList = filter (/x -> not(''p'' `elem` x || ''q'' `elem` x)) myList

Elimina los elementos no deseados de la lista correctamente, sin embargo, no puedo aplicar a Upper en esta lista, ya que el tipo de toUpper es Char.

Lo intenté con el mapa y no funciona.

delAndUpper myList = map toUpper (filter (/x -> not(''p'' `elem` x || ''q'' `elem` x)) myList)

Sé que toUpper en esta línea de código obtiene una lista como valor y, por lo tanto, no puede funcionar, pero sabe cómo bajar un nivel en la lista y aplicar el mapa a Superior.

Me podría ayudar.

¡Gracias por adelantado!

Saludos


Ya casi estás allí, solo necesitas un segundo map .

map (map toUpper) (filter (/x -> not(''p'' `elem` x || ''q'' `elem` x)) myList)

Esto es porque String es completamente sinónimo de [Char] en vainilla haskell. Dado que el tipo de mapa es

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

y tenemos

toUpper :: Char -> Char String :: [Char]

Devolveremos otra String , excepto en mayúscula.

Por cierto, ese filtro feo-ish se puede reemplazar haciendo más bonito haciendo que use flechas :) (Piense en esto como funciones más estructuradas)

map (map toUpper) . filter $ elem ''p'' &&& elem ''q'' >>> arr (not . uncurry (||))

Gratuidad? Tal vez, pero un poco genial.


Mapeo de un nivel más profundo

Necesitas usar el map (map toUpper) .

Esto se debe a que tiene [String] lugar de String .

toUpper :: Char -> Char map toUpper :: [Char] -> [Char]

es decir

map toUpper :: String -> String map (map toUpper) :: [String] -> [String]

map toUpper mayúscula una Cadena, haciendo que cada letra en mayúscula, por lo que el map (map toUpper) capitaliza cada Cadena en una lista de Cadenas.

Tu función se vuelve

delAndUpper myList = map (map toUpper) (filter (/x -> not(''p'' `elem` x || ''q'' `elem` x)) myList)

dave4420 hizo una buena sugerencia de que (map.map) toUpper es una manera ordenada de escribir un map (map toUpper) que te ayuda a pensar en dos niveles de lista de forma bastante simple y natural: echa un vistazo a su respuesta también.

¿Podemos desconectar la p y la q?

Preguntó si había una forma más corta de escribir la condición, y no le gustó la codificación dura de `q` `p` . Estoy de acuerdo en que esos bits de `elem` no son bonitos. Pasemos en la lista de letras no permitidas y arreglemos un poco:

delAndUpper omit strings = map (map toUpper) (filter ok strings) where ok xs = not (any (`elem` omit) xs)

Aquí (`elem` omit) comprueba si un personaje está en la lista de los que nos haría omitir la palabra, entonces (any (`elem` omit) xs) verifica si alguno de los caracteres de xs está prohibido. Por supuesto, si ninguno está prohibido, está ok .

Su original delAndUpper ahora sería delAndUpper "pq" , o si también desea rechazar el capital P y Q, delAndUpper "pqPQ" . (Más sobre esto más adelante).

¿Podemos hacerlo más conciso?

Veamos si no podemos escribir ok un poco más corto. Lo primero que pensé fue utilizar pointfree en él (ver mi respuesta a otra pregunta para obtener detalles sobre cómo ejecutarlo en ghci), pero pareció colgarse, así que al usar algunos trucos de transformación estándar, podemos componer not con una función que tome dos argumentos antes de darnos un Bool haciendo (not.).f lugar de not.f como lo haríamos con una función que acaba de darnos un Bool después de la primera entrada. any está tomando (`elem` omit) como su primer argumento. Esto nos da

ok xs = ((not.).any) (`elem` omit) xs

de donde podemos eliminar los xs finales:

ok = ((not.).any) (`elem` omit)

y en línea:

delAndUpper omit strings = map (map toUpper) (filter (((not.).any) (`elem` omit)) strings)

Tampoco estoy interesado en las strings finales:

delAndUpper omit = map (map toUpper).filter (((not.).any) (`elem` omit))

(Podríamos deshacernos del argumento omit también e ir completamente sin puntos, pero eso sería demasiado lento en el camino difícil de leer para mi gusto).

¿Hacia dónde Q?

> delAndUpper "pq" $ words "The Queen has probably never had a parking ticket." ["THE","QUEEN","HAS","NEVER","HAD","A","TICKET."]

¿Es este el comportamiento requerido? Parece extraño excluir cuidadosamente las variantes en minúsculas y luego hacer todo en mayúsculas. Podríamos hacerlo al revés:

upperAndDel omit = filter (((not.).any) (`elem` omit)).map (map toUpper)

dando

> upperAndDel "PQ" $ words "The Queen has probably never had a parking ticket." ["THE","HAS","NEVER","HAD","A","TICKET."]