Я не понимаю, почему этот код typechecks:Неявное принуждение типа?
error1 :: ErrorT String (ReaderT Int IO) Int
error1 = asks id
FYI, то asks
имеет этот тип:
asks :: Monad m => (r -> a) -> ReaderT r m a
С другой стороны, я могу понять, что этот код typechecks :
reader1 :: ReaderT Int IO Int
reader1 = asks id
id
имеет тип a -> a
и есть экземпляр Monad
для IO
, поэтому компилятор может вывести тип. Это понятно для меня.
ErrorT
является NewType и haskell spec состоянием, (в разделе о ньютайпах):
... это создает особый тип, который должен быть явно принуждением или от исходного типа ...
по моей интерпретации, я должен быть в состоянии получить тот же тип, как и в error1
только явно, с каким-то принуждением похожее на это:
reader2 :: ReaderT Int IO (Either String Int)
reader2 = fmap (\i -> Right i) reader1
error2 :: ErrorT String (ReaderT Int IO) Int
error2 = ErrorT reader2
Но, судя по всему, с тех пор, как error1
typechecks просто отлично, у меня есть некоторые знания. Можете ли вы помочь раскрыть его для меня?
импортирует необходимую для запуска примера кода:
import Control.Monad.Error (ErrorT(ErrorT))
import Control.Monad.Reader (ReaderT, asks)
Тип, который вы указываете для 'asks', является типом из' Control.Monad.Trans.Reader'. Однако в 'Control.Monad.Reader'' asks' имеет более общий тип, а именно 'запрашивает :: MonadReader r m => (r -> a) -> m a'. – kosmikus
Если вы используете последнюю версию 'mtl', то' Control.Monad.Reader.asks' имеет тип 'MonadReader r m => (r -> a) -> m a)'. – bheklilr