tipos por pattern listas infinitas funciones ejemplos datos comentarios ciclos casos haskell functional-programming printf currying

por - pattern matching haskell



¿Alimentar elementos de una tupla a una función como argumentos en Haskell? (3)

La función uncurry convierte una función de dos argumentos (al curry) en una función en pares. Aquí está su tipo de firma:

uncurry :: (a -> b -> c) -> (a, b) -> c

Necesitas usarlo en printf , así:

mapM_ (uncurry $ printf "Values: %d %d/n") [(1,100),(2,350),(3,600),(4,200)]

Otra solución es utilizar la coincidencia de patrones para deconstruir la tupla, como esto:

mapM_ (/(a,b) -> printf "Values: %d %d/n" a b) [(1,100),(2,350),(3,600),(4,200)]

En mi programa Haskell, quiero usar printf para formatear una lista de tuplas. Puedo asignar printf sobre una lista para imprimir los valores uno por uno como este:

mapM_ (printf "Value: %d/n") [1,2,3,4] Value: 1 Value: 2 Value: 3 Value: 4

Quiero poder hacer algo como esto:

mapM_ (printf "Values: %d %d/n") [(1,100),(2,350),(3,600),(4,200)] Values: 1 100 Values: 2 350 Values: 3 600 Values: 4 200

Pero esto pasa una tupla a printf, no dos valores separados. ¿Cómo puedo convertir la tupla en dos argumentos para printf?


Una alternativa segura para el Text.Printf a Text.Printf es el paquete de formatting . Text.Printf.printf no garantiza en tiempo de compilación que el número de parámetros de formato se alinee con el número de argumentos y sus tipos. Lea el artículo de Chris Done, ¿Qué hay de malo con printf? por ejemplo.

Un ejemplo de uso:

{-# LANGUAGE OverloadedStrings #-} import Formatting map (uncurry $ formatToString ("Value: " % int % " " % int)) [(1,100), (2,350), ...] map (/(x,y) -> formatToString ("Value: " % int % " " % int) x y) [(1,100), (2,350), ...]

Requiere que la extensión GHC OverloadedStrings funcione correctamente.

Si bien formatToString ("Value: " % int % " " % int) tiene el tipo Int -> Int -> String , el sistema no está en curso y da el tipo (Int, Int) -> String cuyo tipo de entrada coincide con los elementos de la lista .

El proceso de reescritura se puede desglosar; asumiendo f = formatString ("Value: " ...) ,

map (/(x,y) -> f x y) ≡ map (/(x,y) -> uncurry f (x,y)) ≡ map (uncurry f)

Es decir, primero debe desbloquear f para lograr la función que acepta tuplas, y luego debe realizar una Eta-conversion normal ya que /(x,y) -> uncurry f (x,y) es equivalente a simplemente uncurry f . Para imprimir cada línea en el resultado, use mapM_ :

mapM_ (putStrLn . uncurry $ formatToString ...) [(1,100), (2,350), ...]

Si ejecuta hlint YourFile.hs , se le recomendarán estas reescrituras.


mapM_ (/(x,y) -> printf "Value: %d %d/n" x y) [(1,100),(2,350),(3,600),(4,200)]