haskell - How do I use zoom with a MonadState constraint of a newtype? -
i have 2 functions, 1 monadstate constraint of wrapped type, other has monadstate constraint of unwrapped type. i'd seamlessly run second function within first.
for example:
import qualified control.monad.state.strict 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 me should work, yet 3 type checker errors. first:
could not deduce (control.lens.zoom.zoom m0 m int (sum int)) arising use of ‘zoom’ context (mtl.monadstate (sum int) m) bound type signature outer :: mtl.monadstate (sum int) m => m int type variable ‘m0’ ambiguous from searching, impression zoom can't want. (found quote on http://ircbrowse.net/browse/haskell "reltuk: yeah, thats unfortunate downside of lenses zooming forces concrete state monad") guess lines error message stating "m0 ambiguous".
i'd rather not change monadstate constraint concrete monad.
is there other standard way of doing want?
edit:
this 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
zoom has own class overloading, no wonder monadstate doesn't cut it. zoom class covers same ground mtl, although has more complicated machinery. in case, you're not obligated program in concrete monads.
you can try enabling nomonomorphismrestriction , inferring type:
{-# language nomonomorphismrestriction #-} import control.lens.internal.zoom import control.lens import control.monad.state import data.monoid import control.monad.except -- illustration outer = zoom _wrapped' now :t outer gives
outer :: (functor (zoomed m (unwrapped t)), zoom m n (unwrapped t) t, wrapped t) => n (unwrapped t) this isn't pretty, seems work.
> runstate outer (sum 10) (10, sum {getsum = 10}) > runstate (runexceptt outer) (sum 10) :: (either string int, sum int) (right 10,sum {getsum = 10}) edit:
if want specialize sum int outer state, , want have monadstate (sum int) n constraint, suffices:
sumouter :: (functor (zoomed m int), zoom m n int (sum int)) => n int sumouter = zoom _wrapped' suminner suminner :: (mtl.monadstate int m) => m int suminner = mtl.get what monadstate constraint? there's no need write out, because zoom m n s t has monadstate s m , monadstate t n superclasses.
likewise, more general outer function implies monadstate t n.
Comments
Post a Comment