查找haskell中所有括号的组合?

时间:2015-01-06 16:12:14

标签: haskell types

我正在尝试编写一个简单的代码来生成括号的所有组合。但是我遇到了一个简单的类型错误。

balancedParens :: Int -> [String]
balancedParens n
            | n==0 = []
            | otherwise = placeParens 0 1 0 n [""]
          where placeParens x lc rc n mlist
                                | lc == n = mlist
                                | rc == n = mlist
                                | lc < n = placeParens (x+1) (lc+1) rc n ((mlist !! x) ++ "L")
                                | rc < n = placeParens (x+1) lc (rc+1) n ((mlist !! x) ++ "R")

有很多错误,但最突出的是

Couldn't match type ‘Char’ with ‘[Char]’
Expected type: [[Char]]
  Actual type: [Char]
In the first argument of ‘(!!)’, namely ‘mlist’
In the first argument of ‘(++)’, namely ‘(mlist !! x)’

失败,模块加载:无。

((mlist !! x)++“L”)是一个列表,为什么类型错误?怎么匹配[Char]?

1 个答案:

答案 0 :(得分:2)

问题陈述

让我们定义一个平衡字符串是什么,归纳为:

  • ""是平衡的
  • 如果xy达到平衡,则"(" ++ x ++ ")" ++ y达到平衡

所有平衡字符串都可以使用上述规则构建。

有限案例

我们希望枚举具有正确n个括号的所有平衡字符串。我们遵循上面的归纳规则。

paren :: Int -> [String]
paren 0 = [""]
paren n = [ "(" ++ x ++ ")" ++ y
          | m <- [0..n-1] , x <- paren m , y <- paren (n-1-m) ]

在第二条规则中,我们以任何可能的方式将剩余的n-1括号分为两部分。第一部分由m个括号组成,0 <= m <= n-1。第二个因此 由(n-1)-m括号组成。

无限大小

让我们提高标准。我们不仅仅想要特定n的组合,我们想要一个包含所有这些组合的详尽列表。我们可能concat $ map paren [0..]但是这感觉很愚蠢:当我们要连接结果时,为什么我们应该将这个集合划分为括号n的数量?

相反,让我们直接枚举所有无限平衡字符串。 这是Omega monad的工作。我们只需要再次使用归纳规则:

import Control.Monad.Omega

allParen :: Omega String
allParen = return ""
       <|> (\x y -> "(" ++ x ++ ")" ++ y) <$> allParen <*> allParen

这比paren更简单,因为我们永远不需要计算括号的数量。

GHCi的快速测试:

> take 20 $ runOmega allParen
["","()","()()","(())","()()()","(())()","(()())","()(())","(())()()","(()())()","((()))","()()()()","(())(())","(()())()()","((()))()","(()()())","()(())()","(())()()()","(()())(())","((()))()()"]