-- Ausschnitt aus einem einfachen Textverarbeitungssystem -- putInLines: Ein Text soll in Zeilen gleicher Länge transformiert werden. meinText :: String -- ein erster Beispieltext meinText = " Kein anderer \n zeitgenössischer Roman stellt derart ehrlich wie \n hintergründig die Frage nach der \n Identität des modernen Menschen. " lineLen :: Int -- gewünschte Zeilenlänge lineLen = 30 -- ursprünglich vorhandene Leerzeichen, die entfernt werden sollen whiteSpaces :: [Char] whiteSpaces = [' ', '\t', '\n'] isWhite, isNotWhite :: Char -> Bool isWhite c = c `elem` whiteSpaces isNotWhite c = c `notElem` whiteSpaces -- Definition: Ein Wort ist eine Zeichenfolge, die keine whiteSpaces enthält. type Word = String -- splitWords generiert die Wortfolge aus einem Text splitWords :: String -> [Word] splitWords [] = [] splitWords t = getWord t': splitWords (dropWord t') where t' = dropWhile isWhite t -- getWord extrahiert das erste Wort und dropWord entfernt es aus einem Text getWord :: String -> Word getWord [] = [] getWord (c:cs) = if isWhite c then [] else c : getWord cs dropWord :: String -> String dropWord [] = [] dropWord (c:cs) = if isWhite c then cs else dropWord cs -- Eine Zeile ist eine Wortfolge type Line = [Word] -- splitLines generiert eine Zeilenfolge aus einer Wortfolge splitLines :: [Word] -> [Line] splitLines [] = [] splitLines ws = getline lineLen ws : splitLines (dropLine lineLen ws) getline :: Int -> [Word] -> Line -- generiert die erste Zeile getline _ [] = [] getline len (w:ws) | length w <= len = w : restOfLine | otherwise = [] where newlen = len - (length w + 1) restOfLine = getline newlen ws dropLine :: Int -> [Word] -> [Word] -- entfernt die erste Zeile dropLine _ [] = [] dropLine len (w:ws) | length w <= len = restOfWords | otherwise = w:ws where newlen = len - (length w + 1) restOfWords = dropLine newlen ws -- transformiere Text gemäß Spezifkation putInLines :: String -> String putInLines = layout . splitLines . splitWords -- putInLines s = joinLines (splitLines ( splitWords s)) layout :: [Line] -> String layout ls = joinLines (map joinWords ls) joinWords :: [Word] -> String joinWords [] = [] joinWords (w:ws) = w ++ " " ++ joinWords ws joinLines :: [String] -> String joinLines [] = [] joinLines (l:ls) = l ++ "\n" ++ joinLines ls test :: IO() -- Ein erster Test test = putStr (putInLines meinText)