Haskell: Как читать в командной строке args как int?
Я пытаюсь получить значение int из командной строки и передать его функции disp
.
import System(getArgs)
main = do
args <- getArgs
disp $ read $ head args :: Int
disp n = take n $ repeat 'S'
Ошибка, заданная ghc, равна
Couldn't match expected type `Int' with actual type `[Char]'
In the expression: disp $ read $ head args :: Int
In the expression:
do { args <- getArgs;
disp $ read $ head args :: Int }
In an equation for `main':
main
= do { args <- getArgs;
disp $ read $ head args :: Int }
Спасибо.
Ответы
Ответ 1
Проблема заключается в precendence: сигнатуры типов всегда пытаются применить к всему выражению (только в скобках с использованием скобок). Таким образом, ваш disp $ read $ head args :: Int
анализирует как (disp $ read $ head args) :: Int
, что, очевидно, неверно. Вы можете использовать скобки так:
disp (read $ head args :: Int)
или опустить подпись типа, поскольку GHC может вывести его в этом случае:
disp $ read $ head args
Этот код по-прежнему не работает как есть, потому что вы находитесь в монаде IO, поэтому вам нужно произвести действия IO. Вы можете сделать это, распечатав результат, например:
putStrLn $ disp $ read $ head args
Ответ 2
Вы можете инкапсулировать вытягивание целочисленного аргумента командной строки следующим образом:
getIntArg :: IO Int
getIntArg = fmap (read . head) getArgs
Что работает, потому что Monads - это функторы. Или вы можете сделать то же самое с liftM
.
Таким образом ваша функция main
просто станет:
main = do
n <- getIntArg
disp n
Если вы добавите какой-либо тип функции печати в disp
, как описано в других ответах.
Ответ 3
Просто удалите этот явный тип, который вы там добавили, и он будет работать. Имейте веру в вывод типа.:) Добавьте print $ ...
там или что-то подобное, чтобы исправить новую ошибку.
Что происходит, тип take
известен, поэтому также известен тип аргумента, который ожидает disp
. Это Int
. Таким образом, будет применен соответствующий read
.
Сделайте меньше, сделайте больше.