Re: [Haskell-beginners] How can I lift my function taking a function to a Monad?

Hiya,
That would certainly explain why I found it difficult.
Here's the original definition:
liftMLabel :: Monad m => a :-> b -> m a :-> m b
liftMLabel l = label (liftM $ get l) (liftM2 $ set l)
Are here's a sample iteration of me hacking around:
liftMLens :: Monad m => a :-> b -> m a :-> m b
liftMLens l = lens getter modifier
where
getter = liftM $ get l
modifier mf mm = mf >>= \ f -> modify l f `liftM` mm
I only ever seem to replicate liftM2 characteristics when trying to
brute force an implementation. And the implementations get more and
more brutish as time goes on!
It makes me wonder if the implications of fclabels `m a :-> m b` are
radically different now, bearing in mind the original code worked. The
fclabels :-> type operator has convinced the compiler that `m b -> mb`
is required for the actual value modifying function.
Does `m a :-> m b` make sense for the latest releases of fclabels? Is
it just the lifting that's a problem?
Si
On Thu, 10 Dec, 2015 at 3:02 PM, Daniel Bergey
On 2015-12-10 at 07:43, Simon Peter Nicholls
wrote: So I figure I need:
neededLift :: (Monad m) => ((b -> b) -> a -> a) -> (m b -> m b) -> m a -> m a
I don't believe `neededLift` is possible. The type says that given any function `m b -> m b`, you can turn that function into one of type `b -> b` (as input to the lens).

On Thu, Dec 10, 2015 at 10:16 PM, Simon Peter Nicholls wrote: Does `m a :-> m b` make sense for the latest releases of fclabels? Is it
just the lifting that's a problem? Yes, you can still write a function of type Monad m => (a :-> b) -> (m a
:-> m b). But it's gotten a bit trickier as you can tell.
The wrong way is to try to write:
neededLift :: (Monad m) => ((b -> b) -> a -> a) -> (m b -> m b) -> m a -> m
a
which, as Daniel pointed out, is impossible.
So we start with the isomorphisms:
isoL :: (f -> a) -> (a -> f -> f) -> ((a -> a) -> (f -> f))
isoL g s m f = s (m (g f)) f
isoR :: (f -> a) -> ((a -> a) -> (f -> f)) -> (a -> f -> f)
isoR _ m a = m (const a)
It turns out we really only need isoL, but isoR is there for completeness.
Then we write:
liftALabel :: Applicative f => a :-> b -> f a :-> f b
liftALabel l0 = lens g1 m1 where
g1 = fmap (get l0)
s1 = liftA2 (set l0)
m1 = isoL g1 s1
Naturally, monad has been effect-reduced to applicative to admit more legal
programs.
-- Kim-Ee

On Thu, 10 Dec, 2015 at 6:43 PM, Kim-Ee Yeoh
The wrong way is to try to write:
neededLift :: (Monad m) => ((b -> b) -> a -> a) -> (m b -> m b) -> m a -> m a
which, as Daniel pointed out, is impossible.
So we start with the isomorphisms:
isoL :: (f -> a) -> (a -> f -> f) -> ((a -> a) -> (f -> f)) isoL g s m f = s (m (g f)) f isoR :: (f -> a) -> ((a -> a) -> (f -> f)) -> (a -> f -> f) isoR _ m a = m (const a)
It turns out we really only need isoL, but isoR is there for completeness.
Then we write:
liftALabel :: Applicative f => a :-> b -> f a :-> f b liftALabel l0 = lens g1 m1 where g1 = fmap (get l0) s1 = liftA2 (set l0) m1 = isoL g1 s1
Naturally, monad has been effect-reduced to applicative to admit more legal programs.
-- Kim-Ee
Thanks guys, I appreciate your help. You've given me a lot of food for thought here, Kim-Ee, and I'll spin off a new project to explore this in isolation. Si
participants (2)
-
Kim-Ee Yeoh
-
Simon Peter Nicholls