una tuplas sobre promedio opciones multiplicar listas lista hacer funciones encontrar eliminar elemento como basico list haskell types pretty-print

tuplas - Formato de salida de lista en Haskell?



multiplicar haskell (3)

¿Algo como esto?

import Data.List (intercalate) data Foo = Foo String String [Int] fooToLine :: Foo -> String fooToLine (Foo a b cs) = a ++ " | " ++ b ++ " | " ++ intercalate ", " (map show cs)

Ahora, puedes hacer

>>> fooToLine (Foo "Hello" "World" [1, 2, 3]) "Hello | World | 1, 2, 3"

Tengo problemas para tratar de formatear el resultado de una lista de mi propio tipo en Haskell.

Me gustaría algo como esto:

Make | Model | Years(this is a list) <- this would be the headers if you like ------------------- Item1 | Item1 | Item1s,Item1s Item2 | Item2 | Item2s,Items2,Items2

^ Este sería el dato cargado desde mi tipo String String [Int].

¿Cómo haría esto en Haskell?


En general, usamos bibliotecas de "impresión bonita" para hacer un buen resultado formateado. El estándar que debes saber es Text.PrettyPrint . Dado un tipo de datos, puede caminar de ese tipo, creando un documento bien formateado.

Un ejemplo:

import Text.PrettyPrint import Data.List -- a type for records data T = T { make :: String , model :: String , years :: [Int] } deriving Show -- test data test = [ T "foo" "avenger" [1990, 1992] , T "bar" "eagle" [1980, 1982] ] -- print lists of records: a header, then each row draw :: [T] -> Doc draw xs = text "Make/t|/tModel/t|/tYear" $+$ vcat (map row xs) where -- print a row row t = foldl1 (<|>) [ text (make t) , text (model t) , foldl1 (<^>) (map int (years t)) ] -- helpers x <|> y = x <> text "/t|/t" <> y x <^> y = x <> text "," <+> y

Pruebas:

main = putStrLn (render (draw test))

Resultados en:

Make | Model | Year foo | avenger | 1990, 1992 bar | eagle | 1980, 1982

La capacidad de escribir rápidamente impresoras bonitas es una habilidad increíblemente útil.


Aquí hay un generador de tablas generalizado. Calcula el ancho de las columnas para ajustarse a la fila más ancha. El tipo ColDesc permite especificar, para cada columna, la alineación del título, la cadena de título, la alineación de datos y una función para formatear los datos.

import Data.List (transpose, intercalate) -- a type for records data T = T { make :: String , model :: String , years :: [Int] } deriving Show -- a type for fill functions type Filler = Int -> String -> String -- a type for describing table columns data ColDesc t = ColDesc { colTitleFill :: Filler , colTitle :: String , colValueFill :: Filler , colValue :: t -> String } -- test data test = [ T "foo" "avenger" [1990, 1992] , T "bar" "eagle" [1980, 1982, 1983] ] -- functions that fill a string (s) to a given width (n) by adding pad -- character (c) to align left, right, or center fillLeft c n s = s ++ replicate (n - length s) c fillRight c n s = replicate (n - length s) c ++ s fillCenter c n s = replicate l c ++ s ++ replicate r c where x = n - length s l = x `div` 2 r = x - l -- functions that fill with spaces left = fillLeft '' '' right = fillRight '' '' center = fillCenter '' '' -- converts a list of items into a table according to a list -- of column descriptors showTable :: [ColDesc t] -> [t] -> String showTable cs ts = let header = map colTitle cs rows = [[colValue c t | c <- cs] | t <- ts] widths = [maximum $ map length col | col <- transpose $ header : rows] separator = intercalate "-+-" [replicate width ''-'' | width <- widths] fillCols fill cols = intercalate " | " [fill c width col | (c, width, col) <- zip3 cs widths cols] in unlines $ fillCols colTitleFill header : separator : map (fillCols colValueFill) rows

Corriendo:

putStrLn $ showTable [ ColDesc center "Make" left make , ColDesc center "Model" left model , ColDesc center "Year" right (intercalate ", " . map show . years) ] test

Resultados en:

Make | Model | Year -----+---------+----------------- foo | avenger | 1990, 1992 bar | eagle | 1980, 1982, 1983