J'essaie d'imprimer les éléments de ma liste sur de nouvelles lignes, mais je ne peux pas le faire fonctionner;
printElements :: [String] -> IO()
printElements (x:xs) = print x (some kind of newline, then loop?) printElements xs
Donc ça:
["1","2","2","4"]
donnerait:
1
2
3
4
Dans la plupart des cas, vous n'avez pas besoin de programmer une boucle sur une liste, c'est déjà fait. Pour parcourir une liste avec une fonction monadique, vous utiliseriez mapM (et sa variante mapM _ si vous ne vous souciez pas du résultat.)
Si vous utilisez print , pour ["1","2","3","4"]
vous obtiendrez:
Prelude> mapM_ print ["1","2","3","4"]
"1"
"2"
"3"
"4"
Prelude>
print est en fait:
print :: Show a => a -> IO ()
print x = putStrLn (show x)
la fonction show provoque la chaîne "1"
à convertir en "\"1\""
, putStrLn imprime cela et une nouvelle ligne.
Si vous remplacez le print par putStrLn , vous supprimez l'étape de conversion et imprimez directement la chaîne:
Prelude> mapM_ putStrLn ["1","2","3","4"]
1
2
3
4
Prelude>
J'aimerais maintenant proposer une autre solution. La façon Haskell de faire les choses consiste à faire autant que possible de manière pure et à n'utiliser IO que lorsque vous en avez besoin).
Dans ce cas, nous pouvons joindre toutes les chaînes à imprimer avec un \n
, et imprimez toutes les chaînes à la fois.
Pour joindre toutes les chaînes, il existe une fonction pratique: nlines
Prelude> unlines ["1","2","3","4"]
"1\n2\n3\n4\n"
Prelude>
Il ne vous reste plus qu'à l'imprimer; notez que nlines mettez une nouvelle ligne après le dernier élément de la liste, donc nous utiliserons putStr au lieu de putStrLn
Prelude> putStr ( unlines ["1","2","3","4"] )
1
2
3
4
Prelude>
Votre fonction est:
printElements :: [String] -> IO()
printElements [] = return ()
printElements (x:xs) = do putStrLn x
printElements xs
Si vous connaissez déjà les monades, vous pouvez utiliser mapM_
fonction:
printElements :: [String] -> IO()
printElements = mapM_ putStrLn
Remarque: vous devrez peut-être lire le chapitre 8 de lyah .
Au lieu d'une récursivité explicite, vous pouvez utiliser mapM_
pour appeler putStrLn
pour chaque élément. Il fonctionne comme le map
normal pour les listes, mais est utilisé avec une fonction monadique (donc le "M"). La variante de soulignement est utilisée lorsque vous vous souciez uniquement de l'effet secondaire (dans ce cas, l'impression) et que vous ne vous souciez pas du résultat de la fonction mappée.
printElements :: [String] -> IO ()
printElements = mapM_ putStrLn