readYear
- это не Integer
, это действие IO
, которое можно запустить для чтения ввода и преобразования его в целое число - другими словами, IO Integer
.И поскольку это действие IO
, вам понадобится return
, чтобы использовать read year
в результате getYear
.То есть:
getYear :: IO Integer
getYear = do year <- getLine
return (read year)
Это также означает, что вы используете его как intYear <- readYear
вместо let
(ну, вы могли бы, но вы бы сохранили действие ввода-вывода вместо его запуска, и типиз intYear
было бы неправильно).То есть:
numberOfGoods :: IO String
numberOfGoods = do putStrLn "Enter year (2000-2012):\n"
intYear <- readYear
...
do
не распространяется на if
, скорее вам нужно начать заново с do
, если вы хотите последовательность действий в ветви then
или else
,То есть:
else
c <- readIORef connection
...
return i
должно быть примерно:
else do c <- readIORef connection
...
return i
Что касается сокращения пробелов, рассмотрите возможность вставки логики проверки в readYear
.Реализация этого остается в качестве упражнения для читателя;)
В качестве отступления, вам не нужно in
при использовании let
в блоке do
(но только там!), Вы можетепросто заявите:
do do_something
let val = pure_compuation
something_else_using val