-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Capability focusing using lens? #105
Comments
I've managed to hack this in but I'm not quite sure if this is the way to go: newtype WithLens m a = WithLens (m a)
deriving (Functor, Applicative, Monad)
class HasLens super sub | super -> sub where
view :: super -> sub
update :: super -> sub -> super
subState :: HasLens super sub => (sub -> (a, sub)) -> (super -> (a, super))
subState f st = let (v, res) = f (view st) in (v, update st res)
instance (Monoid superState, HasLens superState subState, HasSink tag superState m) => HasSink tag subState (WithLens m) where
yield_ tag v = WithLens (yield_ tag (update mempty v ))
instance (Monoid superState, HasLens superState subState, HasSource tag superState m) => HasSource tag subState (WithLens m) where
await_ tag = WithLens (view <$> await_ tag)
instance (Monoid superState, HasLens superState subState, HasState tag superState m) => HasState tag subState (WithLens m) where
state_ tag f = WithLens (state_ tag (subState f))
focus
:: forall super sub tag m r
. Monoid super
=> HasState tag super m
=> HasLens super sub
=> (forall m'. HasState tag sub m' => m' r) -> m r
focus = zoom @tag @WithLens @'[] @sub Most notably, it requires There is also the problem of the functional dependency on |
Hi @andrevidela , Have you looked at the Capability.Reflection module? It lets you define a dictionary manually for a capability. It does take a bit of wrapping your head around, but it would avoid having to create an ad hoc type class. (if you do build a type class of the sort you did, I would advise adding a tag argument to the class, so that you can attach multiple lenses to a field). |
Thank you, for the pointer, I'll take a look! |
@andrevidela the capability repository contains some examples using the reflection module here. These might help to better understand the approach. |
Hi, apologies, this is neither a feature request nor a bug report. But a question that I did not know where else to ask.
Is there a way to derive a capability using a lens into a state? I understand that the
Field
/HasField
andPos
/HasPos
capabilities relate to their lens counterpats. But in my case I have a lensand a capability
HasState "stateName" b
and I would like to turn it into aHasState "stateName" a
using the lens described above. The ideal type signature would be something likefocus :: HasState t b m => Lens a b -> (forall m' . HasState t a m' => m' r) -> m r
Is there a way to achieve this?
Intuitively, I would assume
zoom
achieves that but I do not see what transformer to use or how to even define one.The text was updated successfully, but these errors were encountered: