2012-01-17 18 views
11

yo estaba tratando de hacer Tic Tac Toe juego para el tutorial mensual y escribió este código para hacer una caja de primera:¿Cómo puedo imprimir una nueva línea correctamente en Haskell?

box :: [String] 
box = ["0 | 1 | 2", 
     "---------", 
     "3 | 4 | 5", 
     "---------", 
     "6 | 7 | 8"] 

consigo esta salida en GHCi:

["0 | 1 | 2\n","---------\n","3 | 4 | 5\n","---------\n","6 | 7 | 8\n"] 

quería llegar :

0 | 1 | 2 
--------- 
3 | 4 | 5 
--------- 
6 | 7 | 8 

¿Cómo puedo imprimir la cuadrícula de esta manera?

+1

¿Qué función está utilizando para emitirlo? – dave4420

+0

No estoy usando ninguna función pero trabajando en el prompt de GHCi –

Respuesta

25

Pruebe algo como:

box = unlines $ ["0 | 1 | 2", 
       "---------", 
       "3 | 4 | 5", 
       "---------", 
       "6 | 7 | 8"] 

Entonces la caja de salida usando putStr:

main = putStr box 

Lo unlines hace es tomar una lista de cadenas y unirlas mediante nuevas líneas. Básicamente, trata la lista de cadenas como una lista de líneas y las convierte en una sola cadena.

putStr simplemente imprime la cadena a STDOUT. Si usó print o GHCi para mirar la cadena en su lugar, las líneas nuevas se representarían como \n en lugar de las nuevas líneas reales. Esto sucede porque la instancia show de String está diseñada para serializar la cadena como la habría ingresado en lugar de imprimirla. Tanto print como GHCi usan show antes de enviar a STDOUT.

Si usted está en la línea de GHCi y quiere ver lo que la cadena en realidad se parece, puede utilizar putStr directamente:

*Main> putStr box 
0 | 1 | 2 
--------- 
3 | 4 | 5 
--------- 
6 | 7 | 8 
*Main> 
+0

@ dave4420: ¡Wow, no estaba prestando atención! Gracias por arreglar mi error. –

+1

No me agradezcas, gracias a mi insomnio. También puede mejorar su respuesta ya sea consistente sobre el uso de 'putStr' /' putStrLn', o al notar la diferencia entre ellos. – dave4420

+1

Ooh, buen punto. Quise usar 'putStr' en todas partes, pero estoy tan acostumbrado a' putStrLn' que simplemente mecanografia por instinto :) –

8

Otro enfoque es

main = mapM_ putStrLn box 

mapM :: Monad m => (a -> m b) -> [a] -> m [b] es el análogo de mapa, pero para las funciones monádicas, su primo subrayado, mapM_ :: Monad m => (a -> m b) -> [a] -> m() no recoge los valores de retorno y por lo tanto puede ser más eficiente. Si los valores de retorno no son interesantes, como putStrLn s, mapM_ es la mejor opción.

+0

@ Daniel ¿Puede decirme si hay alguna forma en la que puedo dar entrada a Maybe Int y convertirla en Int.? Estaba trabajando en el siguiente código. '' code' movimientos = do' 'putStrLn "Introduzca el número de"' ' número <- readLn :: IO Int' number' de impresión número' findposition cuadro = FindIndex (== número) Caja ': : Int' –

+1

@user Si tiene un valor razonable predeterminado para el caso 'Nothing', use' maybe :: b -> (a -> b) -> Maybe a -> b' o 'Data.Maybe.fromMaybe :: a -> Tal vez a -> a'. –

Cuestiones relacionadas