0

几天前刚开始学习 Haskell,我遇到了一些问题。第一个问题涉及打印数字列表。所需的行为如下:

输入:[1,2,3,4,5,6]

输出:1 2 3 | 4 5 6

所以这是一个简单的概念,我只需要用“|”输出列表的元素 每三个数字之间插入一个符号,但我一生都无法弄清楚。似乎我尝试过的大多数东西都涉及字符串,即使我能够将列表变为字符串,例如 ["1", "2", "3", ...] 我所有的方法尝试在自己的行上打印每个数字,这不是我需要的。

任何帮助将不胜感激。

4

4 回答 4

5

使用split包(最近添加到 Haskell 平台):

> import Data.List         -- for intercalate
> import Data.List.Split   -- for chunksOf
> intercalate " | " . map unwords . chunksOf 3 $ map show [1..7]
"1 2 3 | 4 5 6 | 7"

相关文件:chunksOf, unwords, intercalate.

于 2012-11-25T20:41:39.537 回答
3

这是一种方法。

import Data.List (cycle)

format :: Show a => [a] -> String
format = concat . zipWith (++) ("" : cycle [" ", " ", " | "]) . map show

这确实有一个缺点,即三人一组的分组是硬编码的,但概括起来并不难。

于 2012-11-25T20:40:11.633 回答
2

你可以做

threes [] = ""
threes xs = let (front,rest) = splitAt 3 xs in
   unwords (map show front) ++ 
      if null rest then "" else " | " ++ threes rest

给予

*Main> threes [1..10]
"1 2 3 | 4 5 6 | 7 8 9 | 10"

我使用的功能:

splitAt :: Int -> [a] -> ([a], [a])
  -- splitAt 2 "Hello Mum" = ("He","llo Mum")

unwords :: [String] -> String
  -- unwords ["Hello","there","everyone"]
  --        = "Hello there everyone"

null :: [a] -> Bool
null [] = True
null _ = False
于 2012-11-25T20:38:02.293 回答
1

第一部分是最简单的,你需要将数字转换为Strings,

format :: (Num a, Show a) => [a] -> String
format xs = result
  where
    strings = map show xs

这样做。然后我们需要将任何列表分成三个(更一般的n)元素的块。splitAt将列表拆分为所需元素数量的前面部分(如果列表足够长)和剩余部分。在剩余部分上迭代过程,虽然那不是空的,但会导致所需的结果。

chunk :: Int -> [a] -> [[a]]
chunk _ [] = []
chunk n xs = ys : chunk n zs
  where
    (ys, zs) = splitAt n xs

这是一个循环模式,所以有一个组合器,我们也可以写

import Data.List (unfoldr)

chunk :: Int -> [a] -> [[a]]
chunk n = unfoldr split
  where
    split [] = Nothing
    split xs = Just $ splitAt n xs

所以我们可以继续我们的format

format :: (Num a, Show a) => [a] -> String
format xs = result
  where
    strings = map show xs
    chunks = chunk 3 strings

然后我们需要"|"在所有块之间插入 a ,这是由intercalatefrom完成的Data.List,最后,将所有字符串与它们之间的空格连接起来,就是unwords这样,所以

format :: (Num a, Show a) => [a] -> String
format xs = result
  where
    strings = map show xs
    chunks = chunk 3 strings
    result = unwords $ intercalate "|" chunks

或者

format = unwords . intercalate "|" . chunk 3 . map show
于 2012-11-25T20:47:24.100 回答