2010-12-03 20 views
6

में हैकेल में फ़ंक्शंस की सूची को Encapsulating किसी ने कहा कि हो सकता है कि मैं होस्केल में उचित कोड कैसे "प्राप्त" नहीं हो सकता। यही कारण है कि किसी को पूरी तरह से सही होना चाहिए, के रूप में मैं अपने सभी Haskell कोड लग रहा है, लेकिन सरल कार्यों वास्तव में बदसूरत है (कम से कम इस तरह के जावा या सी के रूप में एक "मानक" भाषा में मेरी 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 के लिए काम करने के लिए इस की आवश्यकता होगी) मैं शुरू में एक 2 डी मैट्रिक्स है जो मैं आपरेशन के एक दृश्य के लिए लागू किया है, जब तक मुझे मिल गया वांछित परिणाम।

यह काम करता है, लेकिन अब मैं एक ही फ़ंक्शन में इस तर्क को समाहित करना चाहता हूं (चलो इसे matrix_transf पर कॉल करें)। वर्तमान कोड क्या matrixExpValues और canonicalSt वापसी से जुड़ा हुआ है, और मैं की तरह

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

आलोचना के सभी प्रकार का स्वागत है (मैं इसे की जरूरत है तो मैं सुधार कर सकते हैं!) मेरा मानना ​​है कि अच्छा हास्केल कोडर होगा कुछ करना चाहते हैं शायद इसे पूरी तरह से अलग तरीके से देखें और यही वह है जिसे मैं जानना चाहता हूं!

उत्तर

8

सबसे पहले मैं यह कहना चाहता हूं कि जो मैं आपको दिखाने के लिए जा रहा हूं वह इष्टतम नहीं है (उदाहरण के लिए केनीटीएम का कोड पूरी तरह से बेहतर दिखता है।) लेकिन मैं आपको दिखाना चाहता हूं कि अगर आप intXxsToStringXxs को बदलते हैं तो आपका कोड कैसा दिखाई देगा जब संभव परिभाषाओं को इनलाइन जबकि

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

: map (map show) और लगातार नियम लागू होते हैं।

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

Afer काफी: इसके अलावा, यह बेहतर बनाने के लिए, मैं इन नियमों को लागू किया है पुनर्लेखन का लूप, यह आपको यह देगा:

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 
13
  1. लाइब्रेरी को जानें। उदाहरण के लिए, foldl (++) "" xconcat द्वारा बदला जा सकता है, ++ "\t" सामान आदि Data.List.intercalate द्वारा किया जा सकता है, आदि

  2. आप where और let इस्तेमाल कर सकते हैं स्थानीय 'चर' को परिभाषित करने के।

मान लें आप तो मैं लिखते थे

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

मजेदार कैसे पिछले समाधान अभी भी प्रत्येक फ़ील्ड के बाद टैब से अलग-अलग कॉलन के बाद टैब का इलाज करते हैं। जब मैं एक टेबल डंप करता हूं, तो मैं आमतौर पर प्रत्येक फ़ील्ड को टैब के साथ समाप्त होने के बजाय टैब के साथ शुरू करने के साथ व्यवहार करता हूं। मुझे यह भी लगता है कि @ केनीटीएम का संस्करण अधिक पठनीय है:

matrix_transf mev cs = 
    unlines $ zipWith processEntry mev cs 
    where processEntry mev_entry cs_entry = 
      concatMap show cs_entry ++ ":" ++ 
      concapMap (("\t" ++) . show) mev_entry