monad-control icon indicating copy to clipboard operation
monad-control copied to clipboard

Access to a in StM m a

Open nikomi opened this issue 10 years ago • 2 comments

I'm trying to create a lifted version of function f in base monad b (imported qualified as B):

f :: (Monad m, MonadBaseControl b m) => m Bool -> m Bool
f g = control $ \runInBase -> B.f $ runInBase g

runInBase returns b (StM m a) which is expected by restoreM, therefore B.f should obviously be of type b (StM m a) -> b (StM m a). This works if B.f actually is of type b c -> b c with c ~ StM m a and B.f most likely just passing the data through. If B.f requires an explicit type - e.g. b Bool -> b Bool as in this sample - this fails with a compiler error on Bool vs. StM m Bool.

What am I missing? Is there a way to apply B.f to the a in StM m a while keeping the monadic state?

f g = control $ \runInBase -> apply B.f $ runInBase g

where apply converts the given function from b a -> b a to b (StM m a) -> b (StM m a), i.e.

apply :: (b a -> b a) -> b (StM m a) -> b (StM m a)

If there is not I think it might be good if there were - together with an apply_ for

apply_ :: (b a -> b ()) -> b (StM m a) -> b (StM m ())

What do you think?

nikomi avatar Jan 05 '16 09:01 nikomi

I was just needing this. I think I'm going to fork it, expose StT and StM to the typeclass with fundeps, then make an Extractable class, which gives a stT a -> a function. Then, in case you were using MaybeT or something, only support with that class would grant you access. I'll link my PR here when it's made.

athanclark avatar May 10 '17 21:05 athanclark

I made a controversial port, let me know what you think:

  • http://hackage.haskell.org/package/monad-control-aligned-0.0.1/docs/Control-Monad-Trans-Control-Aligned.html -- exposes the StT type chosen at the contraint level
  • http://hackage.haskell.org/package/extractable-singleton-0.0.1/docs/Data-Singleton-Class.html -- constraint for being able to "take out" the * argument-as-constructive-data in a * -> * type.

Law:

forall x. (liftBaseWith $ \runInBase -> runSingleton <$> runInBase x) == x

athanclark avatar May 13 '17 21:05 athanclark