我是haskell的新手,我正在尝试编写一个字符串拆分函数
delim = '|'
splitStr::[Char]->[[Char]]->[[Char]]
splitStr list y
| sL > 0 && sL < length(list) = splitStr (drop (sL+1) list) [subList]++y
| otherwise = [subList]++y
where
subList = takeWhile (\x -> x /= delim) list
sL = length(subList)
split s = splitStr s []
但是,上面的代码总是以相反的顺序返回字符串
Main> split "foo|bar|java|python"
["python","java","bar","foo"]
从y++[subList]
更改为[subList]++y
仍然会产生相同的结果。
我知道可能有更好的方法,但我想知道为什么会发生这种情况。
答案 0 :(得分:5)
splitStr (drop (sL+1) list) [subList]++y
这被解析为(splitStr (drop (sL+1) list) [subList])++y
。您想要的可能是splitStr (drop (sL+1) list) ([subList]++y)
。
答案 1 :(得分:5)
除了sepp2k所说的内容之外,还有一些关于如何改进代码的内容:
在您的代码中,您不需要累加器,因为您可以利用代码懒惰。我重写了你的代码,就像我一样:
split :: Char -> String -> [String]
split delim "" = []
split delim s = chunk : split delim rest where
(chunk,_:rest) = break (==delim) s
它是如何运作的?我将字符串拆分为第一个字符,即等于分隔符。我返回该部分并将该函数递归调用到列表的其余部分。这非常有效,因为Haskell在需要之前不会评估列表的其余部分。