我一直在尝试在 Haskell 中创建一个函数,该函数将一个包含列表的列表作为输入,并且(听起来可能很简单)我希望这个函数检查输入是否是具有 (m,n) 维度的正确表. 如果不是,它将返回(0,0)
。例如,如果我输入:
[[1,7,2,1],[2,2,7,8],[3,2,0,1]]
我去拿:
(3,4)
我需要这个函数来拒绝我程序中的无效输入。
首先,要回答您的实际问题,请不要(0, 0)
用作例外结果。您的函数类型应为:
matrixDim :: [[a]] -> Maybe (Int, Int)
如果矩阵无效,则结果为Nothing
。现在首先检查第一个子列表的长度是多少。我假设一个矩阵必须至少有一行和一列:
matrixDim [] = Nothing
Maybe
现在您可以使用作为 monad的事实:
matrixDim (xs:xss) = do
let w = length xs
guard (w > 0)
(w', h) <- matrixDim xss <|> return (w, 0)
guard (w == w')
return (w, h + 1)
现在让我们回到手头的实际问题:列表不是您想要的。对于此类应用程序,更好的数据类型是在其中一个Data.Array.*
模块中定义的数组。一个更具实验性的替代方案是使用repa ,您可以免费获得并行化。
dim :: [[a]] -> (Int, Int)
dim ls = let x = length ls
ys = map length ls
in case ys of
h:t -> if all (==h) t then (x, h) else (0, 0)
[] -> (0, 0)