You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中实现[[Double]]类型列表的跨行索引式打印

解决Haskell中[[Double]]类型数据的跨行索引打印问题

我曾成功实现过两个子列表的打印操作,但现已遗忘具体步骤,目前需要处理任意数量等长子列表的[[Double]]类型数据。输入示例[[1,2,3],[1,2,3],[1,2,3]]的期望输出为:

1 1 1
2 2 2
3 3 3

我计划使用mapM_,并通过printf控制打印格式,但当前代码是按子列表逐行打印,而非按索引跨行打印。现有代码如下:

import Text.Printf ( printf )

print_row :: Double -> IO ()
print_row r = do
    printf "%9.6f" r

print_rows :: [[Double]] -> Int -> IO ()
print_rows r i = do
    mapM_ print_row (r !! i)

main :: IO ()
main = do
    let rs = [[1,2,3],[1,2,3],[1,2,3]]
        n  = length rs - 1
    mapM_ (print_rows rs) [0..n] 

解决方案

核心思路是先转置列表——把原列表的列转换为行,这样就能直接按行打印转置后的每个子列表。Haskell的Data.List模块提供了transpose函数可以完成这个操作。

修改后的代码如下:

import Text.Printf (printf)
import Data.List (transpose)

-- 打印单个元素,带指定格式
printElement :: Double -> IO ()
printElement x = printf "%9.6f" x

-- 打印一行元素:逐个打印元素后换行
printTransposedRow :: [Double] -> IO ()
printTransposedRow row = do
    mapM_ printElement row
    putStrLn ""

main :: IO ()
main = do
    let rs = [[1,2,3],[1,2,3],[1,2,3]]
        transposedRs = transpose rs
    mapM_ printTransposedRow transposedRs

代码说明

  • transpose rs会将输入的[[1,2,3],[1,2,3],[1,2,3]]转换为[[1,1,1],[2,2,2],[3,3,3]],完全匹配期望的每行输出结构。
  • printTransposedRow函数处理单行输出:先用mapM_ printElement打印该行所有元素,再通过putStrLn ""换行,保证每行输出独立。
  • 最后用mapM_ printTransposedRow遍历转置后的列表,逐行打印即可实现需求。

不依赖内置transpose的实现(可选)

如果不想依赖Data.List的transpose,可以自己实现针对等长子列表的转置逻辑:

transpose' :: [[a]] -> [[a]]
transpose' [] = []
transpose' ([]:xs) = transpose' xs
transpose' ((x:xs):xss) = (x : map head xss) : transpose' (xs : map tail xss)

将代码中的transpose替换为transpose'即可,效果完全一致。

内容的提问来源于stack exchange,提问作者Pompan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:29:58