有人说我可能不会“理解”如何在Haskell中编写正确的代码。有人肯定是完全正确的,因为我觉得我所有的haskell代码,但更简单的函数真的很难看(至少与我使用Java或C++等“标准”语言编写的OOP代码相比):
mev = matrixExpValues 5 4 3
cs = canonicalSt 4 3
cs_t1 = map (foldl (++) "") (map (map show) cs)
cs_t2 = map (++ ":") cs_t1
mev_t1 = intXxsToStringXxs mev
mev_t2 = map (map (++ "\t")) mev_t1
mev_t3 = map (foldl (++) "") mev_t2
res1 = zipWith (++) (map (++ "\t") cs_t2) mev_t3
res2 = map (++ "\n") res1
final_result = foldl (++) "" res2使用mev和cs:
*Main> mev
[[2,-2,-2,-6],[4,2,0,-2],[2,2,4,4],[6,4,2,2],[6,4,2,6]]
*Main> cs
[[0,0,4],[0,1,3],[0,2,2],[1,1,2]](这些值是手工输入的,我需要它来为任意的mev和cs工作!)我最初有一个2D矩阵,我对它应用了一系列操作,直到我得到了想要的结果。
这是可行的,但现在我想将所有这些逻辑封装在一个函数中(让我们称之为matrix_transf)。当前代码与matrixExpValues和canonicalSt返回的内容绑定在一起,我希望有如下内容
matrix_transf mev cs =
...all those transformations
...until I get to final_result所有的批评都是受欢迎的(我需要它,这样我才能改进!)我相信优秀的Haskell程序员可能会以一种完全不同的方式来处理这个问题,这也是我想知道的!
发布于 2010-12-04 00:00:34
首先,我想说我将要向您展示的并不是最优的(例如,KennyTM的代码看起来要好得多)。但我想向您展示一下,如果您将intXxsToStringXxs更改为map (map show)并继续应用该规则,您的代码将是什么样子:
map f (map g xs) ==> map (f.g) xs在可能的情况下内联定义。此外,为了让它看起来更好,我应用了以下规则:
foldl (++) "" concatconcat (map f xs) concatMap f xsconcatMap (++ "\n") unlines==>
经过相当长时间的重写后,它会给你这样的结果:
cs_t3 = map ((++ ":\t") . concatMap show) cs
mev_t3 = map (concatMap ((++"\t") . show)) mev
final_result = unlines (zipWith (++) cs_t3 mev_t3) 我知道它看起来并不是很好,但是你不需要花太长时间就会发现你可以像这样写matrix_transf:
matrix_transf mev cs = unlines (zipWith (++) (starts cs) (endings mev))
starts = map ((++ ":\t") . (concatMap show))
endings = map (concatMap ((++"\t") . show)) 或者甚至像这样:
matrix_transf mev cs = unlines . zipWith (++) starts $ endings
where starts = map ((++ ":\t") . (concatMap show)) cs
endings = map (concatMap ((++"\t") . show)) mev 发布于 2010-12-03 18:00:58
foldl (++) "" x可以替换为concat,++ "\t"等内容可以由Data.List.intercalate完成,等等。where和let来定义本地use假设您想要将这两个列表转换为
004: 2 -2 -2 -6
013: 4 2 0 -2
...然后我会写下
import Data.List
matrix_transf mev cs =
unlines $ zipWith processEntry mev cs
where processEntry mev_entry cs_entry =
concatMap show cs_entry ++ ":\t" ++
intercalate "\t" (map show mev_entry)*Main> putStrLn $ matrix_transf [[2,-2,-2,-6],[4,2,0,-2],[2,2,4,4],[6,4,2,2],[6,4,2,6]] [[0,0,4],[0,1,3],[0,2,2],[1,1,2]]
004: 2 -2 -2 -6
013: 4 2 0 -2
022: 2 2 4 4
112: 6 4 2 2(请注意,这与不存在尾随制表符的函数不同。)
发布于 2013-03-13 06:30:48
有趣的是,以前的解决方案仍然将冒号后的制表符与每个字段后的制表符区别对待。转储表时,我通常将每个字段视为以制表符开头,而不是以制表符结尾。我也认为@KennyTM的版本更具可读性:
matrix_transf mev cs =
unlines $ zipWith processEntry mev cs
where processEntry mev_entry cs_entry =
concatMap show cs_entry ++ ":" ++
concapMap (("\t" ++) . show) mev_entryhttps://stackoverflow.com/questions/4343951
复制相似问题