0
votes

this function should tokenize a String:

    split s c xs i j =
        if head s == c
        then split s c (subStr s i j : xs) j (j + 1)
        else if j == length s
        then (subStr s i j) : xs
        else split s c xs i j + 1
    subStr s i j = take j(drop i s)

However I get the following error msg: No instance for (Num [[Char]]) arising from a use of 'split' Possible fix: add an instance declaration at (Num [[Char]])

Thanks.

Ok function is now:

split s c xs i j =
        if j == length s
        then (subStr s i j) : xs
        else if head (drop j s) == c
        then split s c (subStr s i j : xs) (j + 1) (j + 1)
        else split s c xs i (j + 1)

subStr s i j = take j(drop i s)

now when I apply the function with the following args: split "123,456,789" ',' [] 0 0 I get the result ["789", "456,789", "123"] what's happening here?

1
You should include your type signature for the function. It makes it a bit easier for us to tell what you're trying to do. but my initial guess is that you just need to parenthesize j+1 on the second to last line.genisage
I agree with cdk that this function could be rewritten more clearly. But if you just want this one to work, make substr s i j = take (j-i) (drop i s)genisage

1 Answers

2
votes

The problem is on the line else split s c xs i j + 1. It seems like you're trying to add 1 to the result of split. You probably forgot parens around (j + 1)

I'll assume split returns a [String], yes?

Edit: Your function is difficult to follow. The strange ordering is probably a result of you prepending substrings on the 3rd line (subStr s i j) : xs.

Try rewriting your function using takeWhile, dropWhile :: (a -> Bool) -> [a] -> [a], or better yet, a proper string processing library like ByteString which provides

Data.ByteString.Char8.split :: (Char -> Bool) -> ByteString -> [ByteString]