2016-08-30 7 views
1

Я относительно новичок в Haskell. Теперь я пытаюсь лучше понять Reader Monad. Кажется, что более ясная цель и использование этого. Но в Haskell при просмотре функции :t reader я вижу reader :: MonadReader r m => (r -> a) -> m a. Что означает ограничение этого типа? Когда я пытаюсь построить Reader, напримерПросьба уточнить поведение типа Reader Monad

let myR = reader (\x -> x + 10) 

Я вижу ошибки

<interactive>:21:11: 
No instance for (MonadReader a0 m0) arising from a use of `reader' 
The type variables `m0', `a0' are ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance MonadReader r' m => 
      MonadReader r' (Control.Monad.Trans.Cont.ContT r m) 
    -- Defined in `Control.Monad.Reader.Class' 
    instance MonadReader r ((->) r) 
    -- Defined in `Control.Monad.Reader.Class' 
    instance (Control.Monad.Trans.Error.Error e, MonadReader r m) => 
      MonadReader r (Control.Monad.Trans.Error.ErrorT e m) 
    -- Defined in `Control.Monad.Reader.Class' 
    ...plus 10 others 
In the expression: reader (\ x -> x + 10) 
In an equation for `myR': myR = reader (\ x -> x + 10) 

<interactive>:21:27: 
No instance for (Num a0) arising from a use of `+' 
The type variable `a0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance Num Double -- Defined in `GHC.Float' 
    instance Num Float -- Defined in `GHC.Float' 
    instance Integral a => Num (GHC.Real.Ratio a) 
    -- Defined in `GHC.Real' 
    ...plus three others 
In the expression: x + 10 
In the first argument of `reader', namely `(\ x -> x + 10)' 
In the expression: reader (\ x -> x + 10) 

Очевидно, что я должен добавить подпись типа:

let myR = reader (\x -> x + 10) :: Reader Int Int 

Это работает, но как я мог следует из этого определения читателя reader :: MonadReader r m => (r -> a) -> m a, что я должен определить его как Reader Int Int?

(В случае Может быть, например, let m5 = return 5 :: Maybe Int это, кажется, ясно, для меня, наверное, из-за Может быть, имеет один параметр типа, я не уверен)

+0

В чем заключен контекст? Я могу написать 'let myR = (\ x -> x + 10)' в приглашении GHCi, с 'myR :: (Num a, MonadReader a m) => m a', а' myR 5' - 15. – chepner

ответ

1

Хотя было бы в состоянии по умолчанию Int Haskell Безразлично» t по умолчанию Monad - Reader.

let myR = reader (\x -> x + 10) :: Num a, MonadReader a m => m a 

примерно то, что находит тип проверки, то он применяет правила для дефолта Num к Int и получает.

let myR = reader (\x -> x + 10) :: MonadReader Int m => m Int 

Однако это не имеет значение по умолчанию, определенное для MonadReader так должен вернуть неоднозначную ошибку в этой точке.

Все не потеряно, но вы можете аннотировать какую-то другую часть программы, если вы не хотите комментировать myR, для проверки типа нужно в конце концов сказать, какой MonadReader вы хотите.

Смежные вопросы