【发布时间】:2018-05-14 14:22:20
【问题描述】:
我的目标是编写一个函数来将嵌套括号字符串解析为相应的列表:
parseParens "()" --> []
parseParens "(())" --> [[]]
parseParens "((()()))" --> [[[],[]]]
首先我发现我不能轻易指定定义返回值的类型。我可以这样做:
parseParens :: String -> [[[[t]]]]
但是我怎么说它是无限嵌套的呢?我猜 Haskell 不允许这样做。
我的解决方案
我想出了自己的数据类型:
data InfiniteList = EmptyList | Cons InfiniteList InfiniteList deriving (Show)
还有一个使用它的解析器函数:
parseParens :: String -> InfiniteList
parseParens ('(':xs) =
if remainder == ""
then result
else error "Unbalanced parenthesis"
where (result, remainder) = parseToClose EmptyList xs
parseParens _ = error "Unbalanced parenthesis"
parseToClose :: InfiniteList -> String -> (InfiniteList, String)
parseToClose acc "" = error "Unbalanced parenthesis!"
parseToClose acc (')':xs) = (acc, xs)
parseToClose acc ('(':xs) = parseToClose (concatInfLists acc (Cons result EmptyList)) remainder
where (result, remainder) = parseToClose EmptyList xs
concatInfLists :: InfiniteList -> InfiniteList -> InfiniteList
concatInfLists EmptyList ys = ys
concatInfLists (Cons x xs) ys = Cons x (concatInfLists xs ys)
像这样工作:
parseParens "()" --> EmptyList
parseParens "(())" --> Cons EmptyList EmptyList
parseParens "((()()))" --> Cons (Cons EmptyList (Cons EmptyList EmptyList)) EmptyList
如何改进?
肯定有更好的方法来做到这一点。也许甚至有办法为此使用内置的 List 数据类型?
【问题讨论】:
-
data Nested a = Flat a | Nested (Nested [a])。Nested a值由 nNested构造函数组成,由包含as 的 n 深度嵌套列表的Flat构造函数终止。
标签: list parsing haskell infinite