2010-10-19 14 views
5

कार्यक्रम '0' और '1' लंबाई एन के सभी संभव संयोजनों वापसी के बारे में सवालमेरी पहली Haskell कार्यक्रम

addToElement :: String -> String -> String 
addToElement element symbol = element ++ symbol 

addOneToElement :: String -> String 
addOneToElement element = addToElement element "1"     

addZeroToElement :: String -> String 
addZeroToElement element = addToElement element "0"     

processListOnce :: [String] -> [String] 
processListOnce lst = do 
    let s1 = map addOneToElement lst 
    let s2 = map addZeroToElement lst 
    s1 ++ s2 

processList :: [String] -> Integer -> [String] 
processList lst 1 = processListOnce lst 
processList lst n = do 
      let tmp = processListOnce(lst) 
      processList tmp (n - 1) 

{-      
processList2 :: [String] -> Integer -> [String] 
processList2 lst n = iterate (map processListOnce) lst !! n 
-} 

main = do 
    let s = processList ["0", "1"] 2 
    let ss = show s 
    putStrLn ss 

यह अगर तुम मेरी मदद मेरी पहली हास्केल प्रोग्राम तो मैं आभारी होंगे है:

  • सबसे पहले सभी pls मेरे कोड हास्केल-मार्ग को दोबारा प्रतिक्रिया दें। मैं पहले से ही एक जादू refactring पता:

    Control.Monad.replicateM n [0,1] 
    

    लेकिन इस समाधान का अध्ययन प्रयोजनों :) लिए अच्छा नहीं है

  • मैं ProcessList2 बजाय ProcessList क्यों उपयोग नहीं कर सकते और त्रुटि मिलती है:

    all_possible_combinations.hs:44:51: 
    Couldn't match expected type `[Char]' against inferred type `Char' 
    Expected type: [String]] 
    Inferred type: [String] 
    In the second argument of `iterate', namely `lst' 
    In the first argument of `(!!)', namely 
    `iterate (map processListOnce) lst' 
    
    • क्या प्रक्रिया सूची में 'tmp' चर को छोड़ने (उपयोग नहीं) करने का कोई तरीका है? मैंने कोशिश की है, लेकिन त्रुटि मिली:

      processList :: [String] -> Integer -> [String] 
      processList lst 1 = processListOnce lst 
      processList lst n = processList processListOnce(lst) (n - 1) 
      
      
      all_possible_combinations.hs:39:32: 
      Couldn't match expected type `[String]' 
      against inferred type `[String] -> [String]' 
      In the first argument of `processList', namely `processListOnce' 
      In the expression: processList processListOnce (lst) (n — 1) 
      In the definition of `processList': 
      processList lst n = processList processListOnce (lst) (n — 1) 
      

अग्रिम धन्यवाद।

उत्तर

5

Is there any way to skip (not use) the 'tmp' variable in the processList? I have tried, but got the error:

इस परिभाषा ने गलत प्राथमिकता का उपयोग किया है। आप लिखना चाहिए

processList lst n = processList (processListOnce lst) (n - 1) 
-- #       ^    ^

Why I can not use ProcessList2 instead ProcessList and get error:

processListOnce पहले से ही एक [String] -> [String] कार्य है। यदि आप map processListOnce का उपयोग करते हैं तो यह [[String]] -> [[String]] फ़ंक्शन बन जाएगा। इस प्रकार, map हटा दें।

processList2 lst n = iterate processListOnce lst !! n 
8

यह Haskelly बनाने के बारे में, यहाँ एक समाधान है कि शुद्ध जादू नहीं है (replicateM हो सकता है के रूप में)

onesAndZeroes 0 = [[]] 
onesAndZeroes n = [x:xs | x <- [0,1], xs <- onesAndZeroes (n-1)] 

जब से तुम हास्केल के लिए नए हैं, तो आप इसे समझ में नहीं आता है, यह list comprehensions पढ़ने में मदद कर सकता है।

+0

+1 सुंदर कोड :-) – fortran

+0

पाठक आश्चर्यचकित हो सकता है कि यह वास्तव में प्रतिलिपि के रूप में गैर-जादुई (गैर-) जादुई है - वास्तव में, यह वही है जो 'प्रतिकृति एम एन [0,1] 'करता है। [0,1] पर इस परिभाषा को सारणीबद्ध करना (यानी, इसे हार्ड-कोडेड के बजाय पैरामीटर बनाना), यह परिभाषा तब सूची के लिए _exactly_ replicateM होगी। [[]] को 'वापसी []' में बदलना और 'समान' ऑपरेशन के साथ 'डू' ब्लॉक की सूची समझ प्रतिलिपि बनाने की पूरी तरह से उपयुक्त परिभाषा उत्पन्न करेगी। मुझे एक महत्वाकांक्षी Haskelist के लिए एक अच्छा अभ्यास की तरह लगता है :) – mokus

+0

@mokus यदि दो कार्यों ने एक ही काम नहीं किया है, तो यह सही नहीं होगा? = डी लेकिन वास्तव में 'replicateM n x' को नियंत्रण में' अनुक्रम (प्रतिलिपि एन एक्स) 'के रूप में परिभाषित किया गया है। मोनाड और अनुक्रम को फ़ोल्डर का उपयोग करके परिभाषित किया गया है। हालांकि सूचीकरण को अपमानित करते हुए हमें 'f 0 = वापसी []' और 'f n = do {x <- [0,1]; xs <- f (n-1); वापसी (x: xs)}'। तो प्रतिकृति एम एफ में किए गए रिकर्सन करने के लिए एक सूची का उपयोग करता है। लेकिन जैसा कि आप कहते हैं कि यह एक प्रतिलिपि बनाने के लिए पूरी तरह से उपयुक्त होगा। – HaskellElephant

8

First of all pls refactore my code Haskell-way. I already know one magic refactring:

Control.Monad.replicateM n [0,1] 

but this solution is not good for studying purposes :)

वास्तव में, जबकि मैं निश्चित रूप से किसी हास्केल के लिए नए तरह के एक समाधान के साथ आने की उम्मीद नहीं है, मुझे लगता है कि समझने इस संस्करण प्रयोजनों के अध्ययन के लिए बहुत अच्छा होगा।

नियमित replicate फ़ंक्शन बहुत आसान है: यह उसी तत्व की एक सूची बनाता है जो कई बार दोहराया जाता है। यह भी replicateM क्या करता है की दिशा में पहला कदम है:

> replicate 2 ["0", "1"] 
[["0", "1"], ["0", "1"]] 

कुछ एक monadic में monadic मूल्यों [m a] की एक सूची मोड़, "अनुक्रम" तत्वों की Monad के अनुसार सूची क्या replicateM करता है के दूसरे चरण मूल्यों की सूची m [a]।यह कुछ अर्थों में प्रत्येक monadic मूल्य की संरचना "गठबंधन" है, जहां "गठबंधन" का विशिष्ट अर्थ विशिष्ट monad पर निर्भर करता है।

Monad के रूप में, सूचियां जैसी कई संभावनाओं का प्रतिनिधित्व करती हैं। तो जब हम मूल्यों को "क्रमबद्ध" करते हैं, इसका मतलब है कि प्रत्येक चरण में, प्रत्येक संभावना को अलग से कोशिश की जाती है, और सभी संभावित परिणाम एकत्र किए जाते हैं।

तो, ["0", "1"] दो अलग-अलग संभावनाओं का प्रयास करने वाला प्रतिनिधित्व करने वाला एक monadic value है। [["0", "1"], ["0", "1"]] उस monadic मूल्य की एक सूची दो बार दोहराया गया है। उस सूची को अनुक्रमित करने के लिए, हम सूची के पहले तत्व से प्रत्येक संभावना लेते हैं, इसे परिणाम सूची के प्रमुख के रूप में उपयोग करते हैं, फिर अंत तक पहुंचने तक जारी रखें। क्योंकि संभावनाओं के प्रत्येक समूह में एक ही है, अंतिम परिणाम प्रत्येक संभव आइटम के सभी संभव संयोजनों है:

> replicateM 2 ["0", "1"] 
[["0","0"],["0","1"],["1","0"],["1","1"]] 
0

एक अन्य समाधान:

onesAndZeroes n = combo n ["0", "1"] 
    where combo 1 cs = cs 
      combo n cs = combo (n-1) (f cs) 
      f = concatMap (\x -> ['0':x, '1':x]) 
दूसरों मुझे लगता है कि replicateM मेरी पहली पसंद होगा जैसा

, लेकिन अगर मैं इससे बचाना चाहता था तो यह मेरा समाधान होगा। सूची समझ समाधान से शायद कम स्पष्ट/संक्षिप्त, लेकिन मुझे पूंछ कॉल रिकर्सन काफी सुरुचिपूर्ण लगता है।