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

dev*_*ium 6 haskell functional-programming

有人说我可能没有"得到"如何在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
Run Code Online (Sandbox Code Playgroud)

mevcs的:

*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]]
Run Code Online (Sandbox Code Playgroud)

(这些值手打字,我将需要此为任意的工作mevcs!)我最初有我对其应用操作的顺序,直到我得到了想要的结果的二维矩阵.

这有效,但现在我想将所有这些逻辑封装在一个函数中(让我们称之为matrix_transf).当前的代码与什么matrixExpValuescanonicalSt返回有关,我想有类似的东西

matrix_transf mev cs = 
    ...all those transformations
    ...until I get to final_result
Run Code Online (Sandbox Code Playgroud)

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

ken*_*ytm 13

  1. 了解图书馆.例如,foldl (++) "" x可以替换concat,++ "\t"等等可以通过等等来完成Data.List.intercalate.

  2. 您可以使用wherelet定义本地"变量".

假设您要将2个列表转换为表单

004:    2    -2   -2   -6
013:    4    2    0    -2
...
Run Code Online (Sandbox Code Playgroud)

然后我会写

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)
Run Code Online (Sandbox Code Playgroud)
*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
Run Code Online (Sandbox Code Playgroud)

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


Has*_*ant 8

首先,我想说的是什么,我要告诉你的是不是最佳的(例如KennyTM的代码看起来好多了.)但是,我想告诉你,如果你改变你的代码是什么样子intXxsToStringXxsmap (map show)和不断应用规则 :

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

尽可能在内联定义.另外,为了让它看起来更好,我已经应用了这些规则:

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

相当一部分重写,它会给你这个:

cs_t3  = map ((++ ":\t") . concatMap show) cs 
mev_t3 = map (concatMap ((++"\t") . show)) mev 
final_result = unlines (zipWith (++) cs_t3 mev_t3) 
Run Code Online (Sandbox Code Playgroud)

我知道它看起来并没有那么好,但现在不应该花太多时间来弄清楚你可以matrix_transf像这样写:

matrix_transf mev cs = unlines (zipWith (++) (starts cs) (endings mev))

starts  = map ((++ ":\t") . (concatMap show)) 
endings = map (concatMap ((++"\t") . show))     
Run Code Online (Sandbox Code Playgroud)

或者甚至喜欢这样:

matrix_transf mev cs = unlines . zipWith (++) starts $ endings
    where starts  = map ((++ ":\t") . (concatMap show)) cs 
          endings = map (concatMap ((++"\t") . show)) mev 
Run Code Online (Sandbox Code Playgroud)