我正在开发一个函数来将带括号的数字串转换为树。例如,
treeFromString "((1)((3)(4)))" == Right (Nd (Lf 1) (Nd (Lf 3) (Lf 4)))
字符串
这是我的尝试。我假设一个格式良好的字符串来解决一个更简单的问题,但类型签名应该是Either String (BinL' Int)
。
import Data.Char
data BinL' a = Lf a | Nd (BinL' a) (BinL' a) deriving Show
treeFromString :: String -> BinL' Int
treeFromString [] = undefined
treeFromString ('(':cs) = case span isDigit cs of
("", remaining) -> treeFromString cs
(digits, remaining) -> Nd (Lf (read digits)) (treeFromString remaining)
型
当传入的参数是一个空列表时,我应该返回什么值?
我的一般方法是实现我想要的东西的明智方法吗?
编辑:
有一个互补函数可以将树转换为带括号的字符串。我正在开发的函数应该执行相反的转换。示例:showBinL' :: Show a => BinL' a -> String
个
showBinL' (Nd (Lf 1) (Nd (Lf 3) (Lf 4)))
"((1)((3)(4)))"
型
1条答案
按热度按时间2q5ifsrm1#
如果你不太关心效率,我推荐标准的初学者友好的方法:
事物的解析器
是一个字符串函数
到配对列表
事物和弦。
--格雷厄姆赫顿
而且,您很幸运:语言标准
Read
类将其解析器放在这个框架中。字符串
因此,如果您正在构建一种能够顺利处理这种类型的机制,那么当您需要读取一个数字时,您可以清楚地插入
reads
,实际上甚至可以从数字的阅读树推广到任何Read
示例的阅读树。所以这里是我建议你首先尝试实现的类型。如果你必须有一个特定的类型,你可以在之后写一个小的 Package 器来转换它。
型
在常见的情况下,如果字符串解析成功,结果列表将有一个元素,包含树和尚未解析的字符串的后缀(如果有的话);如果解析失败,结果列表应该是空的。
在你坐下来开始编写解析代码之前,最好先试着写下语法。下面是我对一个合理语法的猜测:树是一对括号,包含序列中的两个孩子或叶子的值。像这样:
型
一个实现计划是构建一个小型的解析器库,可以组合这些解析器来生成这种语法。我推荐以下集合:
型
型
型
型
有了这些,你可以直接将上面的语法翻译成解析器:
型