2013-03-16 3 views
8

Я пытаюсь напечатать список целых чисел в этом форматеПрименения putStr к каждому элементу списка

[1] 
[2] 
[3] 

Так что моя функция принимает список целых чисел и возвращает IO() следующим образом:

import System.IO 

printVector :: [Integer] -> IO() 
printVector (x:xs) = putStr("[" ++ show(x) ++ "]" ++ "\n") : printVector xs 

Но GHC дает мне ошибку:

lin-test.hs:5:22: 
Couldn't match expected type `IO()' with actual type `[a0]' 
In the expression: 
    putStr ("[" ++ show (x) ++ "]" ++ "") : printVector xs 
In an equation for `printVector': 
    printVector (x : xs) 
     = putStr ("[" ++ show (x) ++ "]" ++ "") : printVector xs 
Failed, modules loaded: none. 

Теперь я понимаю, что функция будет работать по списку, сначала беря первый элемент «x», а затем с помощью: printVector xs он будет рекурсивно вызывать остальную часть списка, применяя одну и ту же функцию putStr к каждому элементу в списке.

Но я думаю, что моя проблема в том, где я делаю: printVector xs? Может ли кто-нибудь указать, что я делаю неправильно здесь?

+1

Простейшее изменение: '>> printVector xs' вместо': printVector xs'. – luqui

ответ

14

Вам нужно перечислить список, но, поскольку это операции ввода-вывода, вам также необходимо выполнить их (поскольку map вернет список операций ввода-вывода без их выполнения, см. Следующий пример).

sequence $ map (putStrLn . show) [1,2,3,4] 

Существует функция, которая уже делает это, это mapM. Таким образом, пример можно упростить:

mapM (putStrLn . show) [1,2,3,4] 

Другая вещь, которую вы можете сделать, это с помощью mapM_, который использует sequence_ вместо этого и будет игнорировать результат выполнения действия ввода-вывода для каждого из элементов. Поэтому тип возврата будет IO() вместо IO [()] (предыдущий пример).

mapM_ (putStrLn . show) [1,2,3,4] 
+0

Я вижу. Это очень полезная функция. Есть ли способ для меня добавить к этому, скажем, я хочу сделать форматирование, как я написал выше, mapM_ ("[" ++ putStr ++ "]" ++ "\ n". Show) [1,2 , 3,4]. Это, конечно, неправильно, но я бы очень хотел их распечатать так: – Donna

+4

@enkitosh: Разделить IO и форматирование: 'mapM_ (putStr. Format) [1..4]' и 'format x =" [ "++ show x ++"] \ n "". – Vitus

+4

@enkitosh Используйте lambda, 'mapM_ (\ n -> putStrLn $" ["++ show n ++"] ") [1,2,3,4]', или IMO более читаемый, 'import Control. Monad (forM_) 'и' forM_ [1,2,3,4] $ \ n -> putStrLn $ "[" ++ show n ++ "]" '. ('forM_ = flip mapM_') –

Смежные вопросы