2010-12-03 18 views
6

誰かが、Haskellで適切なコードをどうやって "取得"していない可能性があると言いました。私は(少なくとも、JavaやC++などの「標準」言語での私のOOPコードと比較して)すべての私のHaskellコードが、簡単な関数が本当に醜いと感じるように、その誰かが、完全に右である必要がありますと1つの関数でhaskellの関数リストをカプセル化する

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]] 

(これらの値を手入力されたされた、私は任意mevcsのために働くためにこれを必要になります!) 私が最初に私が得たまで、私は一連の操作を適用するには、2D行列を持っています希望の結果。

これはうまくいきましたが、今はすべてのロジックを1つの関数にカプセル化したいと思います(matrix_transfとしましょう)。現在のコードは、私は良いHaskellのコーダーがする信じるものmatrixExpValuescanonicalSt復帰に結びついている、と私は

matrix_transf mev cs = 
    ...all those transformations 
    ...until I get to final_result 

のようなものに批判のすべての種類を持ってしたいと思います(私が改善することができますので、私はそれを必要とする!)大歓迎ですおそらくこれは全く異なる方法でこれに近づき、それが私が知りたいと思っているものです!

答えて

8

最初に、私があなたに見せたいことは最適ではないと言いたいと思います(KennyTMのコードはもっと良く見えます)。intXxsToStringXxsを変更するとコードがどのように見えるかを示したいと思います可能な場合は定義をインライン化しながら、

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

map (map show)と継続的にルールを適用します。また、それは良く見えるように、私はこれらのルールを適用した:かなりのafer

  • 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) 

私はそれがはるかに良く見えませんが、それはあなたがこのようなmatrix_transfを書くことができることを把握するために、今、あまりにも長い間、あなたを取るべきではありません知っている:

matrix_transf mev cs = unlines . zipWith (++) starts $ endings 
    where starts = map ((++ ":\t") . (concatMap show)) cs 
      endings = map (concatMap ((++"\t") . show)) mev 
:このような

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

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

あるいは

13
  1. ライブラリを知っていますか?例えば、foldl (++) "" xconcatに置き換えることができ、など++ "\t"ものはData.List.intercalateによって行うことができる、など

  2. あなたは地元の「変数」を定義するためにwhereletを使用することができます。

は(あなたがして、私は

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 

を記述し、フォーム

004: 2 -2 -2 -6 
013: 4 2 0 -2 
... 

に2つのリストを変換するとし、これはあなたの機能とは異なることに注意してください末尾のタブは存在しません)

0

これまでの解決策では、各フィールドの後にタブとは異なる形でコロンの後ろにタブが表示されていました。私はテーブルをダンプするとき、私は通常、タブで終わるのではなく、タブで始まるものとして各フィールドを扱います。 @KennyTMのバージョンは読みやすくなっていると思います。

matrix_transf mev cs = 
    unlines $ zipWith processEntry mev cs 
    where processEntry mev_entry cs_entry = 
      concatMap show cs_entry ++ ":" ++ 
      concapMap (("\t" ++) . show) mev_entry 
関連する問題