module String where   
import Prelude ()
import Collections
import Stream
import Char

-- Functions given here work on all Sequences of Char, 
-- including the ancient String type.

-- > type String = Sequence seq Char => seq Char
-- Only imagined.

lines :: (Sequence seq Char, Sequence seq (seq Char)) =>
	 seq Char -> seq (seq Char)
lines s | is_empty s = empty
	| otherwise  = take_while (/='\n') s <:
		       case front_view $ drop_while (/='\n') s of
		       (Nothing)        -> empty
		       (Just ('\n', r)) -> lines r

prop_number_of_lines s = length (lines s) == length (filter (=='\n') s) + 1
-- That is, 
prop_last_line_empty s = (last s == '\n') == (last (lines s) == empty)


words :: (Sequence seq Char, Sequence seq (seq Char)) =>
	 seq Char -> seq (seq Char)
words s = let s' = drop_while isSpace s 
          in if is_empty s' then empty
	     else let (w, s') = break isSpace s
		  in w <: words s'


unlines :: (Sequence seq Char, Sequence seq (seq Char)) =>
	    seq (seq Char) -> seq Char
unlines = concat_apply (>:'\n')

unwords :: (Sequence seq Char, Sequence seq (seq Char)) =>
	    seq (seq Char) -> seq Char
unwords ws | is_empty ws = empty
	   | otherwise   = reduce1 (\a b -> a ++ ' '<:b) ws

-- 'unlines' adds an '\n' at the end of _each_ line, while 'unwords'
-- adds a ' ' only _between_ two words.  That's intensional.

