簡體   English   中英

如何在Haskell中的新行上打印部分列表

[英]How to print part of a list on a new line in Haskell

這可能是一個愚蠢的問題,但我對Haskell很新。 (我剛剛開始在幾個小時前使用它。)

所以我的問題是我有一個包含4個元素的列表,我需要在一行上打印兩個,在新行上打印兩個。

這是清單:

let list1 = ["#", "@", "#", "#"]

我需要輸出看起來像這樣:

#@
##

我知道我可以使用以下內容在新行上打印每個元素:

mapM_ putStrLn list1 

但我不知道如何調整這個僅用於在新行上打印列表的一部分

你需要像Data.Text.chunksOf的任意列表,這是我從未見過的,所以我總是重新實現它。

import Data.List (unfoldr)

-- This version ensures that the output consists of lists 
-- of equal length. To do so, it trims the input.
chunksOf :: Int -> [a] -> [[a]]
chunksOf n = unfoldr (test . splitAt n) where
  test (_, []) = Nothing
  test x       = Just x

然后我們可以將[String]轉換為[[String]] ,這是一個列表,每個列表對應一行的String組件。 我們map concat map到該列表以合並其組件中的每一行,然后使用unlines將它們粘合在一起。

grid :: Int -> [String] -> String
grid n = unlines . map concat . chunksOf n

然后我們可以根據需要打印該字符串

main :: IO ()
main = putStrLn $ grid 2 list1

編輯:顯然是有chunksOf在一個相當流行的庫Data.List.Split 根據我的知識,他們的版本與我的相同,盡管它的實現方式略有不同。 我們兩個都應該滿足

chunksOf n xs ++ chunksOf n ys == chunksOf n (xs ++ ys)

每當length xs `mod` n == 0

你可以做:

mapM_ putStrLn [(take 2 list1), (drop 2 list1)]

其中帶有預期元素數的takedrop返回列表。 take 2取兩個元素,然后drop 2滴前兩個元素。

查看tel鏈接Data.List.Split ,可以使用chop構建另一個解決方案。
定義如下的lib,

chop :: ([a] -> (b, [a])) -> [a] -> [b]
chop _ [] = []
chop f as = b : chop f as'
  where (b, as') = f as

然后按照simeon的建議,我們以這一個襯里結束,

let fun n = mapM_ putStrLn . chop (splitAt n)

印章似乎是一個很好的功能,足以在這里提到,以說明一個替代解決方案。 (展開也很棒)。

初學者嘗試:

myOut :: [String] -> IO ()
myOut [] = putStr "\n" 
myOut (x:xs) = 
    do if x=="@"
       then putStrLn x
       else putStr x

       myOut xs



ghci>myOut ["#", "@", "#", "#"]
#@
##
ghci>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM