该程序返回'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)提前致谢.
首先请重构我的代码Haskell-way.我已经知道一个神奇的refactring:
Run Code Online (Sandbox Code Playgroud)Control.Monad.replicateM n [0,1]但这个解决方案不适合学习目的:)
实际上,虽然我当然不希望有新的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)
关于制作Haskelly,这里的解决方案不是纯粹的魔法(因为复制M可能是)
onesAndZeroes 0 = [[]]
onesAndZeroes n = [x:xs | x <- [0,1], xs <- onesAndZeroes (n-1)]
Run Code Online (Sandbox Code Playgroud)
由于您是haskell的新手,如果您不了解它,可能有助于阅读列表推导.
有没有办法在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)
| 归档时间: |
|
| 查看次数: |
448 次 |
| 最近记录: |