2012-01-17 14 views
11

starałem się uczynić Tic Tac Toe gry dla miesięcznego kursu i napisał ten kod, aby pierwsze pole:Jak poprawnie wydrukować znak nowej linii w Haskell?

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

uzyskać to wyjście w GHCi:

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

chciałem dostać :

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

Jak mogę wydrukować taką siatkę?

+1

Jaką funkcję wykorzystuje się do wyprowadzania? – dave4420

+0

Nie używam żadnej funkcji, ale pracuję pod znakiem zachęty GHCi –

Odpowiedz

25

Spróbuj czegoś takiego:

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

wtedy wyjście pudełka za pomocą putStr:

main = putStr box 

Co unlines robi to wziąć listę ciągów i połączyć je ze sobą za pomocą nowej linii. Zasadniczo traktuje listę łańcuchów jako listę linii i przekształca je w jeden ciąg znaków.

putStr po prostu drukuje ciąg do STDOUT. Jeśli użyjesz print lub GHCi do wyświetlenia ciągu znaków, znaki nowej linii będą renderowane jako \n zamiast rzeczywistych znaków nowej linii. Dzieje się tak dlatego, że instancja obiektu String została zaprojektowana tak, aby serializować ciąg znaków, tak jak byś go wprowadził, zamiast go drukować. Zarówno print, jak i GHCi używają show przed wyprowadzeniem do STDOUT.

Jeśli w wierszu GHCi i chcesz zobaczyć, co łańcuch faktycznie wygląda, można użyć putStr bezpośrednio:

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

@ dave4420: Wow, nie zwracałem uwagi! Dzięki za naprawienie mojego błędu. –

+1

Nie dziękuj mi, dziękuję mojej bezsenności. Możesz także poprawić swoją odpowiedź, bądź konsekwentnie używając 'putStr' /' putStrLn' lub zauważając różnicę między nimi. – dave4420

+1

Ooh, dobry punkt. Chciałem użyć 'putStr' przez cały czas, ale jestem tak bardzo przyzwyczajony do' putStrLn', że po prostu wpisuje instynkt :) –

8

Innym podejściem jest

main = mapM_ putStrLn box 

mapM :: Monad m => (a -> m b) -> [a] -> m [b] jest analogiem map, ale w przypadku funkcji monadycznych, jego podkreślony kuzyn, mapM_ :: Monad m => (a -> m b) -> [a] -> m() nie zbiera wartości zwracanych i dlatego może być bardziej wydajny. Jeśli wartości zwracane są nieinteresujące, tak jak w przypadku putStrLn s, lepszym wyborem jest mapM_.

+0

@ Daniel Czy możesz mi powiedzieć, czy jest jakikolwiek sposób, w jaki mogę podać Input Of Int i przekonwertować go na Int. Pracowałem nad następującym kodem. '' code' porusza = do' 'putStrLn "Wpisz numer"' ' numer <- readLn :: IO Int' ' 'print number' findposition numer skrzynki = findIndex (== numer) box: : Int. –

+1

@user Jeśli masz uzasadnione domyślne dla sprawy "Nic", użyj 'może: b -> (a -> b) -> Może a -> b' lub' Data.Maybe.fromMaybe :: a -> Może a -> a'. –

Powiązane problemy