Да, это не очень хорошо задокументированный угол ghci.Когда вы вводите выражение в ghci, оно использует тип выражения, чтобы решить, что делать:
IO ()
: выполнить действие, больше ничего не делать. Show a => IO a
:Запустите действие и print
результат. - любой другой
IO a
: запустите действие, больше ничего не делать. - все остальное: оберните все выражение с помощью
print
.
Как он решает, какой из этих типов имеет вещь?Легко: он пытается унифицировать тип вашего выражения, который каждая из вышеперечисленных подписей по очереди и решить все возникающие ограничения.(Для cognoscenti: это в дополнение к расширенным правилам по умолчанию! Это объясняет, почему это, кажется, по умолчанию m
, даже если ни стандартные правила по умолчанию, ни расширенные правила по умолчанию не говорят, что по умолчаниюиспользуйте.)
Итак, поскольку ваше выражение не объединяется с IO ()
, а объединяется с Show a => IO a
, ghci находит m ~ IO
(и a ~ Int
) во время объединения, обнаруживает, что существует MonadPlus IO
(и Show Int
) экземпляр для разрешения ограничений, запуска вашего действия и печати результата.