Haskell - 连接字符串列表

3

我正在尝试使用递归创建字符串列表。

基本上,我想要取出字符串的一部分直到某个特定点。从那里创建一个列表,然后通过递归处理剩余的字符串。

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\n123\n",那么输出应该是 ["test", "123"]。

谢谢!


你是说[(1,"test"),(2,"123")]对吧?Line是一个元组,不只是一个字符串。 - kennytm
是的,但我专注于“listStr = [getLine] ++ splitLines getRest”这部分。 - Matt
2
你的问题标题有些混淆 - 你并不是想要连接字符串,而是想要将它们分开,这是相反的操作。 - Andrew
是的,我想要连接一个包含字符串的列表。 - Matt
2个回答

3
如果您尝试编译代码,您将收到一条错误消息,告诉您在该行中存在问题。
listStr = [getLine] ++ splitLines getRest

splitLines getRest 的类型应该是 [String],但它的类型是 Document。这很容易理解,因为 [getLine] 是一个字符串列表(实际上只有一个字符串),所以它只能与另一个字符串列表连接,而不能与 int-string 元组的列表连接。

因此,我们可以使用 map 将 Document 中的每个 int-string 元组替换为只有字符串的元组,从而得到一个字符串列表,即:

listStr = [getLine] ++ map snd (splitLines getRest)

将代码行更改为上述内容后,您的代码将编译并正常运行。
但它只是将字符串拼回一起,因为它们本身就是字符列表。
我不确定您为什么会这样想。
您的代码之所以无法编译,是因为我上面解释的splitLines类型错误。一旦您修复了该错误,代码就会像您希望的那样运行,并返回一个整数-字符串元组列表。在任何时候都不会连接字符串。

啊,好的。我在考虑使用map函数,只是不太确定怎么用。 - Matt

3

如果你写这个只是为了练习递归,那么一旦你修复了sepp2k提到的错误,它就没问题了。但在实际代码中,我更喜欢 -

splitLines str = zip [0..] (lines str)

甚至更好
splitLines = zip [0..] . lines

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接