Подтвердить что ты не робот

Печать элементов списка на новых строках

Я пытаюсь распечатать элементы моего списка на новые строки, но я не могу заставить его работать;

printElements :: [String] -> IO()
printElements (x:xs) =  print x (some kind of newline, then loop?) printElements xs

Итак, это:

["1","2","2","4"]

даст:

1
2
3
4
4b9b3361

Ответ 1

В большинстве случаев вам не нужно программировать цикл над списком, это уже сделано. Чтобы перебрать список с монадической функцией, вы должны использовать mapM (и его mapM_, если вам не нужен результат.)

Если вы используете print, для ["1","2","3","4"] вы получите:

Prelude> mapM_ print ["1","2","3","4"]
"1"
"2"
"3"
"4"
Prelude> 

print на самом деле:

print :: Show a => a -> IO ()
print x = putStrLn (show x)

функция show вызывает преобразование строки "1" в "\"1\"", putStrLn печатает это и новую строку.

Если вы замените print на putStrLn, вы удаляете шаг преобразования и печатаете непосредственно строку:

Prelude> mapM_ putStrLn ["1","2","3","4"]
1
2
3
4
Prelude> 

Теперь я хотел бы предложить другое решение. Способ использования Haskell делает все, что в ваших силах, чистым способом и использует только IO, когда вам это нужно.

Итак, в этом случае мы можем объединить все строки, которые будут напечатаны с помощью \n, и сразу же распечатать все строки.

Чтобы соединить все строки, есть удобная функция: unlines

Prelude> unlines ["1","2","3","4"]
"1\n2\n3\n4\n"
Prelude> 

Теперь вам просто нужно распечатать это; обратите внимание, что unlines помещает новую строку после последнего элемента списка, поэтому мы будем использовать putStr вместо putStrLn

Prelude> putStr ( unlines ["1","2","3","4"] )
1
2
3
4
Prelude> 

Ответ 2

Ваша функция:

printElements :: [String] -> IO()
printElements [] = return ()
printElements (x:xs) = do putStrLn x
                          printElements xs

Если вы уже знаете о монадах, вы можете использовать функцию mapM_:

printElements :: [String] -> IO()
printElements = mapM_ putStrLn

Примечание. Возможно, вам придется прочитать главу 8 lyah.

Ответ 3

Вместо явной рекурсии вы можете использовать mapM_ для вызова putStrLn для каждого элемента. Он работает как обычный map для списков, но используется с монадической функцией (таким образом, "M" ). Вариант подчеркивания используется, когда вы заботитесь только о побочном эффекте (в данном случае, о печати) и не заботятся о результате отображаемой функции.

printElements :: [String] -> IO ()
printElements = mapM_ putStrLn