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