Подтвердить что ты не робот

Каков тип возврата 5 в Haskell, если контекст не задан?

В этот вопрос ОП спрашивает, что такое тип выражения return 5, и ответ уже задан в этом вопросе: это общий тип, как можно проверить, набрав

:t return 5

в интерпретаторе Haskell:

return 5 :: (Num a, Monad m) => m a

Конкретная реализация return определяется контекстом, в котором она появляется: вывод типа ограничивает m конкретной монадой, такой как Maybe, [], IO и т.д.

Я также могу заставить интерпретатора выбрать конкретную монаду, указав тип, например.

Prelude> return 5 :: Maybe Int
Just 5
Prelude> return 5 :: [Int]
[5]

и т.д.

Теперь, если я нахожу выражение return 5 без указания типа, я получаю:

Prelude> return 5
5

что довольно удивительно для меня: я предпочел бы, чтобы интерпретатор сказал мне, что он не может выбрать соответствующую реализацию return, потому что он не может вывести монадический тип, который будет использоваться.

Итак, мой вопрос: какая конкретная монада использует Хаскелл здесь? И на основании каких критериев была выбрана эта монада?

ИЗМЕНИТЬ

Спасибо за ответ! На самом деле, если я попытаюсь скомпилировать эту программу:

module Main
where

a = return 5

main :: IO ()
main = putStrLn "This program should not compile"

Я получаю сообщение об ошибке:

No instance for (Monad m0) arising from a use of `return'
The type variable `m0' is ambiguous
Relevant bindings include
  a :: m0 Integer (bound at invalid_return.hs:4:1)
Note: there are several potential instances:
  instance Monad ((->) r) -- Defined in `GHC.Base'
  instance Monad IO -- Defined in `GHC.Base'
  instance Monad [] -- Defined in `GHC.Base'
  ...plus one other
In the expression: return 5
In an equation for `a': a = return 5

Поэтому он работает только в GHCi по причинам, объясняемым Джоном.

4b9b3361

Ответ 1

Монада IO. Это незначительная причуда поведения GHCi. Он пытается унифицировать тип ввода с помощью IO a; если он преуспевает, он запускает действие IO и пытается получить результат show. Если вы дадите ему что-то отличное от действия IO, оно просто пытается show значение.

Его по той же причине, что они дают один и тот же результат:

Prelude> "hello"
"hello"
Prelude> print "hello"
"hello"