2010-09-29 6 views
3

J'essaie de créer une liste de chaînes en utilisant une certaine récursivité.Haskell - Concat une liste de chaînes

Fondamentalement, je veux prendre une partie d'une chaîne jusqu'à un certain point. Créer une liste à partir de cela et ensuite traiter le reste de la chaîne par la récursivité.

type DocName = FilePath 
type Line = (Int,String) 
type Document = [Line] 

splitLines :: String -> Document 
splitLines [] = [] 
splitLines str | length str == 0 = [] 
          | otherwise = zip [0..(length listStr)] listStr 
            where 
             listStr = [getLine] ++ splitLines getRest 
             getLine = (takeWhile (/='\n') str) 
             getRest = (dropWhile (=='\n') (dropWhile (/='\n') str)) 

C'est ce que j'ai obtenu. Mais il ne fait que concaténer les cordes puisqu'elles sont elles-mêmes une liste de personnages. Mais je veux créer une liste de chaînes.

[ "test", "123"] si l'entrée était "test \ n123 \ n"

Merci

+0

Vous voulez dire que '[(1, "test"), (2, "123")]' droite? 'Line' est un tuple, pas seulement une chaîne. – kennytm

+0

oui mais im concentré sur "listStr = [getLine] ++ splitLines getRest" cette partie – Matt

+2

Le titre de votre question est confus - vous n'essayez pas de concaténer des chaînes, vous voulez les séparer, ce qui est le contraire. – Amoss

Répondre

3

Si vous essayez de compiler votre code, vous obtenez un message d'erreur vous indiquant que, dans la ligne

listStr = [getLine] ++ splitLines getRest 

splitLines getRest est de type Document, mais il doit avoir le type [String]. Ceci est assez facile à comprendre, car [getLine] est une liste de chaînes (une liste de chaînes) et donc elle ne peut être concaténée qu'avec une autre liste de chaînes, pas une liste d'int-string-tuples.

Donc, pour résoudre ce problème, nous pouvons utiliser la carte pour remplacer chaque int-string-tuple dans le document avec seulement la chaîne pour obtenir une liste de chaînes, à savoir:

listStr = [getLine] ++ map snd (splitLines getRest) 

Après avoir modifié la ligne au-dessus Votre code va compiler et fonctionner correctement.

Mais il ne fait que concaténer les chaînes, car elles sont elles-mêmes une liste de caractères.

Je ne sais pas pourquoi vous pensez cela.

La raison pour laquelle votre code n'a pas été compilé était en raison du type de splitLines comme je l'ai expliqué ci-dessus. Une fois que vous avez corrigé cette erreur, le code se comporte exactement comme vous le souhaitez, renvoyant une liste de tuples de chaîne entiers. À aucun moment, les chaînes ne sont concaténées.

+0

ahh, d'accord. Je pensais utiliser la carte, je ne savais pas comment. – Matt

3

Eh bien, si vous avez écrit cela juste pour pratiquer la récursion, alors c'est bien une fois que vous corrigez l'erreur mentionnée par sepp2k. Mais dans le code réel, je préférerais -

splitLines str = zip [0..] (lines str) 

Ou encore

splitLines = zip [0..] . lines 
+0

Oui, nous devons créer notre propre code pour lire les lignes. – Matt