Как GHCi выбирает экземпляр класса типа Monad для использования в полиморфных действиях?
Я новичок в Хаскелле, так что это может быть нубовский вопрос.
Когда я делаю return 10 >>= return GHCi показывает 10. Когда я проверяю тип return 10 с :t, он просто говорит return 10 :: (Monad m, Num a) => m a, и я делаю typeOf return 10, я получаю ошибку.
>>= для оценки return 10 >>= return, так какой экземпляр он использовал и как он решил, какой из них использовать?1 ответ:
Это следует из идеи, что GHCi является чем-то вроде гигантского блока
doIO. Всякий раз, когда вы вводите что-то, что является выражением, он сначала пытается увидеть, может ли тип результата быть специализирован на чем-то в формеIO a. Если это возможно, он выполняет действиеIOи просто печатает результат. Только в противном случае он выводит результат самого выражения.Чтобы заставить GHCi перейти к любой конкретной монаде, которую вы хотите, вы можете добавить аннотацию типа. Обратите внимание, как
IOполучает трактуется по-разному (и так же, как трактовалось бы выражение без всякой аннотации).ghci> return 10 >>= return :: Maybe Int Just 10 ghci> return 10 >>= return :: [Int] [10] ghci> return 10 >>= return :: IO Int 10
В стороне, есть совершенно другая проблема относительно того, какой экземпляр
Numвыбран, и это имеет все отношение к нарушению правил и ограничению мономорфизма.