Implementing Haskell#lines
What happens when a string ends in a newline? lines "\n" ⇒ [""], but lines' "\n" ⇒ ["", ""].
ys could have a more informative name. line?
When you find yourself wanting to add new items to the end of a list, consider keeping the list in reverse order, adding items to the front and reversing it when it's done. This avoids needing to use ++. ("Done" is a fuzzy concept when working lazily with infinite lists.)
...but when reinventing the wheel, you needn't reinvent the axle and bearings as well. There is a Prelude function that will parse one line from a string: break. If you use that, you need only handle recursing on the remainder. This is how lines is really implemented.

lines s         =  let (l, s') = break (== '\n') s
                   in  l : case s' of
                                []      -&gt; []
                                (_:s'') -&gt; lines s''