Похоже, вы нашли печально известного MonomorphismRestriction
. Подробнее info .Ссылки прекрасно объясняют, что такое ограничение MonomorphismRestriction и как оно работает.
Вы не ошиблись, ожидая, что написание bind'
без подписи должно "просто работать".Однако иногда компилятору требуется небольшая помощь.Короче говоря, из-за MonomorphismRestriction GHC пытается взять номинально полиморфную сигнатуру bind' :: Monad m => m a -> (a -> m b) -> m b
и сделать ее менее полиморфной, создавая экземпляры некоторых переменных типа.
В вашем случае, похоже, что компилятор хочетbind'
работает только для одного конкретного Monad m
.Без вашего реального кода я не могу сказать наверняка, но рассмотрим следующий пример:
import Debug.Trace
main :: IO ()
main = (>>=) (return "hello") print
bind' = trace "bind" (>>=)
Компилятор выдаст ошибку, аналогичную вашей: Ambiguous type variable m0
Однако, если вы использовать bind'
:
import Debug.Trace
main :: IO ()
main = bind' (return "hello") print
bind' = trace "bind" (>>=)
без ошибок!Это потому, что GHC выводит , что m
должно быть IO
, поскольку bind'
используется в монаде IO
.
В качестве альтернативы, вы можете указать GHC отключить MonomorphismRestriction:
{-# LANGUAGE NoMonomorphismRestriction #-}
import Debug.Trace
main :: IO ()
main = (>>=) (return "hello") print
bind' = trace "bind" (>>=)
и он прекрасно компилируется!