首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将haskell中的函数列表封装在单个函数列表中

将haskell中的函数列表封装在单个函数列表中
EN

Stack Overflow用户
提问于 2010-12-03 17:05:49
回答 3查看 973关注 0票数 6

有人说我可能不会“理解”如何在Haskell中编写正确的代码。有人肯定是完全正确的,因为我觉得我所有的haskell代码,但更简单的函数真的很难看(至少与我使用Java或C++等“标准”语言编写的OOP代码相比):

代码语言:javascript
复制
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

使用mevcs

代码语言:javascript
复制
*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]]

(这些值是手工输入的,我需要它来为任意的mevcs工作!)我最初有一个2D矩阵,我对它应用了一系列操作,直到我得到了想要的结果。

这是可行的,但现在我想将所有这些逻辑封装在一个函数中(让我们称之为matrix_transf)。当前代码与matrixExpValuescanonicalSt返回的内容绑定在一起,我希望有如下内容

代码语言:javascript
复制
matrix_transf mev cs = 
    ...all those transformations
    ...until I get to final_result

所有的批评都是受欢迎的(我需要它,这样我才能改进!)我相信优秀的Haskell程序员可能会以一种完全不同的方式来处理这个问题,这也是我想知道的!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-04 00:00:34

首先,我想说我将要向您展示的并不是最优的(例如,KennyTM的代码看起来要好得多)。但我想向您展示一下,如果您将intXxsToStringXxs更改为map (map show)并继续应用该规则,您的代码将是什么样子:

  • map f (map g xs) ==> map (f.g) xs

在可能的情况下内联定义。此外,为了让它看起来更好,我应用了以下规则:

  • foldl (++) "" concat
  • concat (map f xs) concatMap f xs
  • concatMap (++ "\n") unlines

==>

经过相当长时间的重写后,它会给你这样的结果:

代码语言:javascript
复制
cs_t3  = map ((++ ":\t") . concatMap show) cs 
mev_t3 = map (concatMap ((++"\t") . show)) mev 
final_result = unlines (zipWith (++) cs_t3 mev_t3) 

我知道它看起来并不是很好,但是你不需要花太长时间就会发现你可以像这样写matrix_transf

代码语言:javascript
复制
matrix_transf mev cs = unlines (zipWith (++) (starts cs) (endings mev))

starts  = map ((++ ":\t") . (concatMap show)) 
endings = map (concatMap ((++"\t") . show))     

或者甚至像这样:

代码语言:javascript
复制
matrix_transf mev cs = unlines . zipWith (++) starts $ endings
    where starts  = map ((++ ":\t") . (concatMap show)) cs 
          endings = map (concatMap ((++"\t") . show)) mev 
票数 8
EN

Stack Overflow用户

发布于 2010-12-03 18:00:58

  1. 知道图书馆。例如,foldl (++) "" x可以替换为concat++ "\t"等内容可以由Data.List.intercalate完成,等等。
  2. 您可以使用wherelet来定义本地use

假设您想要将这两个列表转换为

代码语言:javascript
复制
004:    2    -2   -2   -6
013:    4    2    0    -2
...

然后我会写下

代码语言:javascript
复制
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)
代码语言:javascript
复制
*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

(请注意,这与不存在尾随制表符的函数不同。)

票数 13
EN

Stack Overflow用户

发布于 2013-03-13 06:30:48

有趣的是,以前的解决方案仍然将冒号后的制表符与每个字段后的制表符区别对待。转储表时,我通常将每个字段视为以制表符开头,而不是以制表符结尾。我也认为@KennyTM的版本更具可读性:

代码语言:javascript
复制
matrix_transf mev cs = 
   unlines $ zipWith processEntry mev cs
   where processEntry mev_entry cs_entry = 
            concatMap show cs_entry ++ ":" ++ 
            concapMap (("\t" ++) . show) mev_entry
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4343951

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档