I have two functions, one with a MonadState constraint of the wrapped type, the other has a MonadState constraint of the unwrapped type. I'd like to seamlessly run the second function within the first.
import qualified Control.Monad.State.Strict as MTL import Data.Monoid (Sum) import Control.Lens.Zoom (zoom) import Control.Lens.Wrapped (_Wrapped') outer :: (MTL.MonadState (Sum Int) m) => m Int outer = zoom _Wrapped' inner inner :: (MTL.MonadState Int m) => m Int inner = MTL.get
The above seems to me like it should work, yet I get 3 type checker errors. The first:
Could not deduce (Control.Lens.Zoom.Zoom m0 m Int (Sum Int)) arising from a use of ‘zoom’ from the context (MTL.MonadState (Sum Int) m) bound by the type signature for outer :: MTL.MonadState (Sum Int) m => m Int The type variable ‘m0’ is ambiguous
From my searching, I get the impression that
zoom can't do what I want. (found this quote on http://ircbrowse.net/browse/haskell "reltuk: yeah, thats the unfortunate downside of lenses is that zooming forces you to a concrete state monad") I guess that lines up with the error message stating that "m0 is ambiguous".
I'd really rather not change my MonadState constraint into a concrete monad.
Is there some other standard way of doing what I want?
This will not type check:
sumOuter :: (Functor (Zoomed m Int), Zoom m m Int t, Wrapped t, Unwrapped t ~ Int, MTL.MonadState (Sum Int) m) => m Int sumOuter = zoom _Wrapped' sumInner sumInner :: (MTL.MonadState Int m) => m Int sumInner = MTL.get