程序返回“0”和“1”的长度为N的所有可能组合的问题关于我的第一个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
这是我的第一个Haskell程序,所以我会很感激,如果你能帮助我:
首先请你重新编写我的代码Haskell-way。我已经知道了一个神奇的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'
有什么办法可以跳过(不使用)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)
感谢。
+1漂亮的代码:-) – fortran 2010-10-19 09:57:06
读者可能会惊讶的发现,这实际上每一个位都像replicateM一样(非)神奇 - 事实上,这正是'replicateM n [0,1]'所做的。在[0,1]上抽象定义这个定义(即使用一个参数而不是硬编码),这个定义对列表monad来说就是_exactly_ replicateM。将[[]]更改为'return []'并将列表理解转换为具有完全相同操作的'do'块将会产生一个完美合适的replicateM定义。听起来像一个有益的Haskelist好运动:) – mokus 2010-10-19 14:31:03
@mokus如果这两个功能没有做同样的事情,那么它会不会是正确的? = D,但实际上'replicateM n x'在Control.Monad中被定义为'sequence(replicate n x)',序列是使用foldr定义的。然而,解析listcomprehensions我们得到'f 0 = return []'和'f n = do {x < - [0,1]; xs < - f(n-1); return(x:xs)}''。所以replicateM使用一个列表来完成f中的递归。但是,当你说这样做时,完全适合制作复制品。 – HaskellElephant 2010-10-19 23:03:40