I'm new to haskell, I was trying to write a string split function
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 []
However, the above code always returns the String in reverse order
Main> split "foo|bar|java|python"
["python","java","bar","foo"]
changing from y++[subList]
to [subList]++y
still gives the same result.
I know there maybe better ways to do it, but I want to know why the above is happening.
splitStr (drop (sL+1) list) [subList]++y
This is parsed as (splitStr (drop (sL+1) list) [subList])++y
. What you wanted is probably splitStr (drop (sL+1) list) ([subList]++y)
.
Here is, additional to what sepp2k said, something about how to improve your code:
In your code you don't need an accumulator, since you can exploit the codes laziness. I rewrote your code like I would do it:
split :: Char -> String -> [String]
split delim "" = []
split delim s = chunk : split delim rest where
(chunk,_:rest) = break (==delim) s
How does it works? I split the string at the first char, that is equal to the delimiter. I return that part and call the function recursivly onto the rest of the list. This is very efficient, since Haskell won't evaluate the rest of the list until it's needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With