Теория монад очень интересна, и вам стоит окунуться в нее и понять все это глубоко. Но вот в основном неправильный ответ, чтобы помочь вам начать кодирование, не беспокоясь обо всем этом.
Существует два вида вещей: значения и действия . Действия имеют типы, заключенные в IO
, например IO Int
, IO String
, IO (Maybe [Bool])
. Действия - это способ ввода / вывода. Они выполняют некоторые операции ввода-вывода и после завершения возвращают значение типа, который они переносят.
Действия создаются с do
, и обычно последняя строка имеет return <value>
(или является другой действие, в этом случае он использует возвращаемое значение этого). Итак, ваше query
- это действие:
query :: IO Int -- notice the IO
query = do
print ("escoge una columna vacia")
input <- getLine
return (read input)
То, как вы используете действия, связывает их , используя <-
, что вы уже сделали с getLine
. Это можно сделать только в блоке do
. Поэтому, если вы хотите использовать query
в advanceHuman
, вам необходимо связать его:
advanceHuman b = do
input <- query
...
Имя (или шаблон) слева от привязки становится значением типа что бы ни было завернуто в IO
- в данном случае Int
.
Однако я сказал, что do
создает действия. Это означает, что advanceHuman
должен возвращать тип действия:
advanceHuman :: Board -> IO Board
advanceHuman b = do
input <- query
...
Единственными вещами, которые могут быть строками в блоке do, являются действия, либо привязанные к значениям, либо нет, и return <value>
(что, как выясняется, это тоже действие).
Вы должны связать действия, прежде чем использовать их значения. Например, если у вас есть
getX :: IO Int
getY :: IO Int
Тогда вы не можете сказать getX + getY
, чтобы получить их сумму. Вы должны сказать do { x <- getX; y <- getY; return (x + y) }
(или liftA2 (+) getX getY
, но давайте не будем забегать вперед).
Если вы хотите связать имя со значением вместо действия, вы используйте вместо этого let
. Так что в advanceHuman
вы использовали let
, когда вы должны были использовать <-
, потому что query
- это действие.
Надеюсь, это поможет.