Reputation: 2515
What's the difference between
view :: MonadReader s m => Getting a s a -> m a
and
use :: MonadState s m => Getting a s a -> m a
Upvotes: 2
Views: 417
Reputation: 34398
A lens getter gives us a function from its source to its target:
(^.) :: s -> Getting a s a -> a
flip (^.) :: Getting a s a -> s -> a
Any function can be made into a MonadReader
computation, with the argument type of the function as the environment type:
asks :: MonadReader s m => (s -> a) -> m a
That being so, (^.)
can be generalised to any MonadReader
through asks
, giving rise to view
:
view :: MonadReader s m => Getting a s a -> m a
view g = asks (\s -> s ^. g)
(The definitions I'm using here aren't literally the ones you will find in the Control.Lens.Getter
source, but they are equivalent to them as far as results go.)
In a similar way, any function can be made into a MonadState
computation that leaves the state unchanged, with the argument type of the function as the state type:
gets :: MonadState s m => (s -> a) -> m a
Accordingly, (^.)
can also be generalised to any MonadState
through gets
, resulting in use
:
use :: MonadReader s m => Getting a s a -> m a
use g = gets (\s -> s ^. g)
From another angle, view
and use
can be seen as variants of asks
and gets
, respectively, that take a getter as argument, rather than a function directly.
On a final note about view
, functions themselves are instances of MonadReader
. That being so, view
can be used as a prefix/non-operator version of (^.)
.
Upvotes: 0
Reputation: 70407
Taking a look at the type signatures, view
takes a MonadReader
(such as ReaderT
) and use
takes a MonadState
(such as StateT
). Now, view
and use
both have the same objective: extract a reasonable value from the thing we're looking at.
MonadReader
represents read-only state. We can access the value within using ask
. MonadState
represents read-write state, which can be retrieved with get
. So both view
and use
query the internal state of the monad given, but view
calls ask
whereas use
calls get
. Generally speaking, only one will be applicable to your situation.
A look at the source code for the two functions is not particularly enlightening unless you already understand how lenses are implemented (and if you do, then you probably understand the difference between view
and use
), so this is a good example of a situation where the type signatures can be much more enlightening than the code itself.
Upvotes: 4