Haskell了解流程

时间:2011-03-29 18:28:50

标签: haskell

我是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仍然会产生相同的结果。 我知道可能有更好的方法,但我想知道为什么会发生这种情况。

2 个答案:

答案 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在需要之前不会评估列表的其余部分。