Zmieniam kod, który działał wewnątrz monady StateT
, aby działał wewnątrz StateP
z Control.Proxy
. Jednak część mojego kodu (na przykład operator %=
z Control.Lens
) wymaga instancji MonadState
. Czy jest to dla mnie bezpieczne/poprawne, aby dodać taką instancję? Wygląda to jak coś, co jest poprawnie obsługiwane przez bibliotekę (w tym przypadku: Control.Proxy
).Czy mogę ustawić StateP z Control.Proxy jako instancję MonadState?
5
A
Odpowiedz
4
Tak, to jest bezpieczne. Instancja chcesz to:
instance (Monad m, Proxy p) => MonadState s (PS.StateP s p a' a b' b m) where
get = PS.get
put = PS.put
Chcę tylko krótko zauważyć, że w pipes-4.0.0
(który jest na Github) transformatory proxy nie są już konieczne, a te same rozszerzenia są zlecane monada transformatorów w monady bazowej. Oznacza to, że zamiast:
Consumer (StateP s p) a m r
... użyłbyś:
Consumer a (StateT s m) r
Oznacza to, że można to po prostu być w stanie napisać:
lift $ myLens %= f
Ja jednak nadal plan na dodawanie instancji MonadState
dla Proxy
tak, choć może w osobnym pakiecie (nadal nie zdecydowałem, czy włączyć je do głównej biblioteki). Wyglądają tak:
instance (MonadState s m) => MonadState s (Proxy a' a b' b m r) where
put s = lift (put s)
get = lift get
wielkie dzięki! jednak wydaje się to nie do końca poprawne - pojawia się następujący błąd: – ajp
'Miły brak dopasowania Drugi argument" MonadState "powinien mieć rodzaj" * -> * ", , ale" Proxy a 'ab' bmr " ma rodzaj '*' W deklaracji instancji dla 'MonadState s (Proxy a' ab 'bmr)' ' – ajp
usunięcie' r' z typu Proxy powoduje naprawienie tego rodzaju, ale następnie daje inny o niedozwolonej deklaracji instancji – ajp