Haskell word execution

I tried to implement the words function from Data.List, but my implementation doesn't work exactly as I want.

For example, if the input to the function is "tere vana kere", then the output will be ["vana", "kere"] and it skips the first word. But when I add a space before my input "tere vana kere" then the result is correct ["tere", "vana", "kere"]

Can anyone point out the problem. Thank you.

words' :: String -> [String]
words' xs = snd $ foldr (\x acc -> if isSpace x then 
                                    if null (fst acc) then
                                        acc
                                    else
                                        ([], (fst acc): (snd acc)) 
                               else 
                                     (x:fst acc, snd acc)   
                               ) ([],[]) xs

      

+3


source to share


1 answer


OK, so try this:

step x acc =
  if isSpace x
    then
      if null (fst acc)
        then acc
        else ([], (fst acc) : (snd acc))
    else (x : fst acc, snd acc)

words' xs = snd $ foldr step ([], []) xs

      

Now, run this one step at a time: suppose we want words' "ABC DEF GHI"

. We can do it like this:

Prelude> step 'I' ([], [])
("I", [])
Prelude> step 'H' it
("HI", [])
Prelude> step 'G' it
("GHI", [])
Prelude> step ' ' it
("", ["GHI"])
Prelude> step 'F' it
("F", ["GHI"])
Prelude> step 'E' it
("EF", ["GHI"])
Prelude> step 'D' it
("DEF", ["GHI"])
Prelude> step ' ' it
("", ["DEF","GHI"])
Prelude> step 'C' it
("C", ["DEF","GHI"])
Prelude> step 'B' it
("BC", ["DEF","GHI"])
Prelude> step 'A' it
("ABC", ["DEF","GHI"])
Prelude> snd it
["DEF","GHI"]

      

Do you see the problem here?



The problem is that you only "paint" the current word into the wordlist when you see a whitespace character. In particular, you don't clear up when you see the end of the input. You can fix this by replacing snd

:

words' xs = (\ (w, ws) -> w:ws) $ foldr step ([], []) xs

      

As an aside, congratulations for the code to handle multiple consecutive spaces correctly. :-)

EDIT: To keep this nice property:

words' xs = (\ (w, ws) -> if null w then ws else w:ws) $ ...

      

+3


source







All Articles