我试图使用一些递归创建一个字符串列表。
基本上我想把字符串的一部分带到某一点。从中创建一个列表,然后通过递归处理其余的字符串。
type DocName = FilePath
type Line = (Int,String)
type Document = [Line]
splitLines :: String -> Document
splitLines [] = []
splitLines str | length str == 0 = []
| otherwise = zip [0..(length listStr)] listStr
where
listStr = [getLine] ++ splitLines getRest
getLine = (takeWhile (/='\n') str)
getRest = (dropWhile (=='\n') (dropWhile (/='\n') str))
这就是我得到的。但它只是将字符串重新连接在一起,因为它们是字符列表本身。但我想创建一个字符串列表。
[“test”,“123”]如果输入是“test \ n123 \ n”
由于
答案 0 :(得分:3)
如果您尝试编译代码,则会在行
中收到一条错误消息listStr = [getLine] ++ splitLines getRest
splitLines getRest
的类型为Document
,但其类型应为[String]
。这很容易理解,因为[getLine]
是一个字符串列表(以及一个字符串的列表),所以它只能与另一个字符串列表连接,而不是int-string-tuples列表。< / p>
为了解决这个问题,我们可以使用map来替换Document中的每个int-string-tuple,只用字符串来获取字符串列表,即:
listStr = [getLine] ++ map snd (splitLines getRest)
将行更改为上面后,您的代码将编译并运行正常。
但它只是将字符串重新组合在一起,因为它们本身就是字符列表。
我不确定你为什么这么认为。
您的代码未编译的原因是由于我在上面解释的splitLines
的类型。一旦修复了该错误,代码就会按照您的意愿运行,返回整数字符串元组的列表。字符串连接在一起。
答案 1 :(得分:3)
好吧,如果你写这个只是为了练习递归,那么一旦你修复了sepp2k提到的错误就可以了。但在实际代码中,我更愿意 -
splitLines str = zip [0..] (lines str)
甚至
splitLines = zip [0..] . lines