2012-01-17 13 views
11

Stavo cercando di fare Tic Tac Toe gioco per il tutorial mensile e ha scritto questo codice per fare una scatola prima:Come posso stampare correttamente una nuova riga in Haskell?

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

ottengo questo output in GHCi:

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

volevo arrivare :

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

Come posso stampare la griglia in questo modo?

+1

Quale funzione stai utilizzando per l'output? – dave4420

+0

Non sto utilizzando alcuna funzione ma sto lavorando al prompt GHCi –

risposta

25

Prova qualcosa di simile:

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

poi uscita la casella con putStr:

main = putStr box 

Cosa unlines fa è prendere una lista di stringhe e unirsi a loro insieme usando nuove righe. In pratica tratta l'elenco di stringhe come un elenco di linee e le trasforma in una singola stringa.

putStr stampa la stringa su STDOUT. Se si utilizzava print o GHCi per esaminare la stringa, le nuove righe venivano visualizzate come \n anziché come nuove righe effettive. Ciò accade perché l'istanza show di un String è progettata per serializzare la stringa come se fosse stata inserita anziché stampata. Entrambi print e GHCi utilizzano show prima di eseguire l'output su STDOUT.

Se siete al prompt GHCi e volete vedere che cosa la stringa si presenta come, è possibile utilizzare putStr direttamente:

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

@ dave4420: Wow, non stavo prestando attenzione! Grazie per aver corretto il mio errore. –

+1

Non ringraziarmi, grazie alla mia insonnia. Puoi anche migliorare la tua risposta consistendo nell'uso di 'putStr' /' putStrLn', o osservando la differenza tra loro. – dave4420

+1

Ooh, buon punto. Intendevo usare 'putStr' dappertutto, ma sono così abituato a' putStrLn' che viene semplicemente digitato dall'istinto :) –

8

Un altro approccio è

main = mapM_ putStrLn box 

mapM :: Monad m => (a -> m b) -> [a] -> m [b] è l'analogo di mappa, ma per le funzioni monadiche, il suo cugino sottolineato, mapM_ :: Monad m => (a -> m b) -> [a] -> m() non raccoglie i valori restituiti e può quindi essere più efficiente. Se i valori restituiti non sono interessanti, come per putStrLn s, mapM_ è la scelta migliore.

+0

@ Daniel Puoi dirmi se c'è un modo in cui posso dare input di Maybe Int e convertirlo in Int. Stavo lavorando al seguente codice. 'Codice delle ' mosse = do' 'putStrLn "Inserire il numero"' ' numero <- readLn :: IO Int' scatola ' findposition numero di casella = FindIndex (== numero) 'stampa number': : Int' –

+1

@user Se si dispone di un valore predefinito ragionevole per il caso 'Nothing', utilizzare' maybe :: b -> (a -> b) -> Forse a -> b' o 'Data.Maybe.fromMaybe :: a -> Forse a -> a'. –

Problemi correlati