Learn You a Haskell shows the lines
function:
It takes a string and returns every line of that string in a separate list.
Example:
>lines' "HELLO\nWORLD\nHOWAREYOU" ["HELLO","WORLD","HOWAREYOU"]
Here's my implementation:
lines' :: String -> [String]
lines' [] = []
lines' xs = lines'' xs []
where lines'' [] ys = ys : []
lines'' (x:xs) ys
| x == '\n' = ys : lines'' xs []
| otherwise = lines'' xs (ys ++ [x])
Please critique it. Also, when using an accumulator
value (such as ys
in lines''
), I don't know how to use the :
function instead of ++
.
1 Answer 1
What happens when a string ends in a newline?
lines "\n"
⇒[""]
, butlines' "\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 howlines
is really implemented.lines s = let (l, s') = break (== '\n') s in l : case s' of [] -> [] (_:s'') -> lines s''
-
\$\begingroup\$ thanks, Anonymous. Excellent suggestions for improvement. Would you implement #1 by simply adding that special case
lines' "\n" = [""]
? \$\endgroup\$Kevin Meredith– Kevin Meredith2014年05月13日 23:47:24 +00:00Commented May 13, 2014 at 23:47 -
\$\begingroup\$ No, because it wouldn't cover other strings ending in newlines (e.g.
lines "a\n"
⇒["a"]
), and because it can be done without a special case by recursing appropriately. \$\endgroup\$Anonymous– Anonymous2014年05月14日 00:32:02 +00:00Commented May 14, 2014 at 0:32