2012-01-17 38 views
11

Tôi đã cố gắng để làm Tic Tac Toe trò chơi cho các hướng dẫn hàng tháng và viết mã này để tạo ra một hộp đầu tiên:Làm cách nào để in dòng mới trong Haskell?

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

tôi nhận được kết quả này trong GHCi:

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

tôi muốn để có được :

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

Làm cách nào để in lưới như thế này?

+1

Bạn đang sử dụng chức năng nào để xuất nó? – dave4420

+0

Tôi không sử dụng bất kỳ chức năng nào nhưng làm việc tại GHCi prompt –

Trả lời

25

Hãy thử một cái gì đó như:

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

Sau đó, sản lượng hộp bằng putStr:

main = putStr box 

unlines làm là lấy một danh sách các chuỗi và tham gia cùng họ với nhau bằng dòng mới. Về cơ bản nó xử lý danh sách các chuỗi như là một danh sách các dòng và biến chúng thành một chuỗi đơn.

putStr chỉ in chuỗi thành STDOUT. Nếu bạn đã sử dụng print hoặc GHCi để xem chuỗi thay vào đó, dòng mới sẽ được hiển thị dưới dạng \n thay vì dòng mới thực tế. Điều này xảy ra vì cá thể show của String được thiết kế để sắp xếp chuỗi ký tự như bạn đã nhập vào chuỗi thay vì in nó. Cả hai print và GHCi sử dụng show trước khi xuất ra STDOUT.

Nếu bạn đang ở dấu nhắc GHCi và muốn xem những gì các chuỗi thực sự trông như thế nào, bạn có thể sử dụng putStr trực tiếp:

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

@ dave4420: Wow, tôi không chú ý! Cảm ơn bạn đã sửa lỗi của tôi. –

+1

Đừng cảm ơn tôi, cảm ơn chứng mất ngủ của tôi. Bạn cũng có thể cải thiện câu trả lời của bạn bằng cách nhất quán về việc sử dụng 'putStr' /' putStrLn' hoặc bằng cách ghi nhận sự khác biệt giữa chúng. – dave4420

+1

Ooh, tốt. Tôi có nghĩa là sử dụng 'putStr' trong suốt, nhưng tôi đã quen với' putStrLn' rằng nó chỉ được gõ theo bản năng :) –

8

Một cách khác là

main = mapM_ putStrLn box 

mapM :: Monad m => (a -> m b) -> [a] -> m [b] là tương tự của bản đồ, nhưng đối với các hàm đơn điệu, người anh em họ của nó, mapM_ :: Monad m => (a -> m b) -> [a] -> m() không thu thập các giá trị trả về và do đó có thể hiệu quả hơn. Nếu các giá trị trả về không quan tâm, như đối với putStrLn s, mapM_ là lựa chọn tốt hơn.

+0

@ Daniel Bạn có thể vui lòng cho tôi biết nếu có bất kỳ cách nào mà tôi có thể cung cấp đầu vào của Có thể Int và chuyển đổi nó thành Int. Tôi đã làm việc trên đoạn mã sau. 'code' ' di chuyển = do' 'putStrLn "Nhập số" ' ' số <- readLn :: IO Int' ' in number' 'findposition số hộp = findIndex (== số) hộp: : Int' –

+1

@user Nếu bạn có mặc định hợp lý cho trường hợp 'Không có gì', hãy sử dụng 'có thể :: b -> (a -> b) -> Có thể a -> b' hoặc 'Data.Maybe.fromMaybe :: a -> Có thể a -> a'. –

Các vấn đề liên quan