我有Data.Map (Int, Int) [String]
代表游戏的棋盘(我假设在地图上的某个位置可以有多个棋子)。让我们说我有以下地图:
fromList [ ( (0,1) , ["piece1", "piece2"] )
, ( (2,2) , ["piece3", "piece4"] ) ]
我要做的是打印表格,在这种情况下是一张3×3的桌子,地图的元素位于指定的位置,而其余的空格是空的或者有一个' x&# 39 ;.我曾尝试使用foldl和地图以及2的组合,但我不知道应该怎么做。我必须提到我对Haskell很新。任何帮助都会很棒!
输出应为:
x | piece1piece2 | x
x | x | x
x | x | piece3piece4
答案 0 :(得分:1)
以下是一些可以帮助您入门的代码。它通过迭代板的(行,列)坐标来工作。在迭代中,它查找要为该位置打印的字符串,在失败时默认为“x”。最后,电路板一次打印一行。
最终的格式并不完全是你的想法,但它应该让你在那里大部分时间。
from_unixtime
答案 1 :(得分:0)
我将开始导入Data.Map.Strict
。一般来说,这样做的方法是
import qualified Data.Map.Strict as M
import Data.Map.Strict (Map)
你有一个Map (Int, Int) String
,你需要打印一个正方形的字符串数组。看来你需要做的第一件事就是计算数组的尺寸。我们可以用索引折叠来做到这一点。对于这份工作来说,它看起来很不错
foldlWithKey' :: (a -> k -> b -> a) -> a -> Map k b -> a
Hrmm ......那些类型变量不是很有用。让我重新评论一下:
foldlWithKey'
:: (acc -> key -> elem -> acc)
-> acc
-> Map key elem
-> acc
此函数获取累加器的初始值,以及指示如何为映射中的每个键和元素修改该累加器的函数。让我们做一个代表董事会维度的类型:
data Dim = Dim { rows :: !Int, cols :: !Int }
现在我们可以写
getDim :: Map (Int, Int) a -> Dim
getDim = M.foldlWithKey' update (Dim 0 0)
where
update (Dim rs cs) (r, c) _
= Dim (max rs (r + 1)) (max cs (c + 1))
对于Map
中的每个条目,我们会根据需要调整行数和列数。
现在我们知道了电路板的尺寸,让我们构建一个更适合打印的表示。最简单的方法是迭代行号和列号,查找映射中的对。让我们开始写一个函数来获得一行:
getRow :: Int -> Dim -> Map (Int, Int) a -> [Maybe a]
getRow r (Dim {cols = cs}) m =
[ M.lookup (r, c) | c <- [0 .. cs - 1] ]
此处Nothing
表示该密钥不在地图中,Just whatever
表示该密钥。
现在我们可以用它来获取所有行:
getRows :: Dim -> Map (Int, Int) a -> [[Maybe a]]
getRows dim@(Dim {rows = rs}) m =
[ getRow r dim m | r <- [0 .. rs - 1] ]
现在我们可以考虑展示了!我将把此留给您,但我建议您考虑使用Data.List.intercalate
和map
将每一行转换为字符串。