关于我的第一个haskell计划的问题

dem*_*mas 5 haskell

该程序返回'0'和'1'长度N的所有可能组合.

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

这是我的第一个Haskell计划,所以如果你帮助我,我将感激不尽:

  • 首先请重构我的代码Haskell-way.我已经知道一个神奇的refactring:

     Control.Monad.replicateM n [0,1]
    
    Run Code Online (Sandbox Code Playgroud)

    但这个解决方案不适合学习目的:)

  • 为什么我不能使用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'
    
    Run Code Online (Sandbox Code Playgroud)
    • 有没有办法在processList中跳过(不使用)'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)
      
      Run Code Online (Sandbox Code Playgroud)

提前致谢.

C. *_*ann 9

首先请重构我的代码Haskell-way.我已经知道一个神奇的refactring:

Control.Monad.replicateM n [0,1]
Run Code Online (Sandbox Code Playgroud)

但这个解决方案不适合学习目的:)

实际上,虽然我当然不希望有新的Haskell想出这样的解决方案,但我认为理解这个版本对学习目的非常有用.

常规replicate函数非常简单:它创建了重复相同元素的列表.这也是第一步replicateM:

> replicate 2 ["0", "1"]
[["0", "1"], ["0", "1"]]
Run Code Online (Sandbox Code Playgroud)

第二步replicateM是根据Monad元素对序列进行"序列化" ,将一个monadic值列表转换为monadic值[m a]列表m [a].这样做是在某种意义上"结合"每个monadic值的结构,其中"combine"的具体含义取决于特定的monad.

作为一个Monad,列表代表了尝试多种可能性的东西.因此,当我们"排序"这些值时,这意味着在每个步骤中,每个可能性都会单独尝试,并收集所有可能的结果.

因此,["0", "1"]是一个代表尝试两种不同可能性的monadic值.[["0", "1"], ["0", "1"]]是重复两次的monadic值的列表.为了对该列表进行排序,我们从列表的第一个元素中获取每种可能性,将其用作结果列表的头部,然后继续直到结束.因为每组可能性是相同的,所以最终结果是每个可能项目的所有可能组合:

> replicateM 2 ["0", "1"]
[["0","0"],["0","1"],["1","0"],["1","1"]]
Run Code Online (Sandbox Code Playgroud)


Has*_*ant 8

关于制作Haskelly,这里的解决方案不是纯粹的魔法(因为复制M可能是)

onesAndZeroes 0 = [[]]
onesAndZeroes n = [x:xs | x <- [0,1], xs <- onesAndZeroes (n-1)]
Run Code Online (Sandbox Code Playgroud)

由于您是haskell的新手,如果您不了解它,可能有助于阅读列表推导.


ken*_*ytm 5

有没有办法在processList中跳过(不使用)'tmp'变量?我试过了,但得到了错误:

该定义使用了错误的优先级.你应该写

processList lst n = processList (processListOnce lst) (n - 1)
-- #                            ^                   ^
Run Code Online (Sandbox Code Playgroud)

为什么我不能使用ProcessList2而不是ProcessList并获取错误:

processListOnce已经是一个[String] -> [String]功能.如果你使用map processListOnce它将成为一个[[String]] -> [[String]]功能.因此,删除map.

processList2 lst n = iterate processListOnce lst !! n
Run Code Online (Sandbox Code Playgroud)