Я изменяю некоторый код, который раньше выполнялся внутри монады StateT
, чтобы он выполнялся внутри монады StateP
из Control.Proxy
. Однако для части моего кода (например, для оператора %=
из Control.Lens
) требуется экземпляр MonadState
. Безопасно ли для меня просто добавить такой экземпляр? Это похоже на то, что наиболее правильно обрабатывается библиотекой (в данном случае Control.Proxy
).
могу ли я сделать StateP из Control.Proxy экземпляром MonadState?
Ответы (1)
Да, это безопасно. Нужный вам экземпляр:
instance (Monad m, Proxy p) => MonadState s (PS.StateP s p a' a b' b m) where
get = PS.get
put = PS.put
Хочу только вкратце отметить, что в pipes-4.0.0
(который есть на Github) прокси-трансформеры больше не нужны и те же расширения вынесены на аутсорсинг монад-трансформеров в базовой монаде. Это означает, что вместо:
Consumer (StateP s p) a m r
... вы бы использовали:
Consumer a (StateT s m) r
Это означает, что вы тогда просто сможете написать:
lift $ myLens %= f
Тем не менее, я все равно планирую добавить MonadState
экземпляров для Proxy
, хотя, возможно, в отдельном пакете (я еще не решил, включать ли их в основную библиотеку). Они будут выглядеть так:
instance (MonadState s m) => MonadState s (Proxy a' a b' b m r) where
put s = lift (put s)
get = lift get
person
Gabriel Gonzalez
schedule
23.06.2013
огромное спасибо! однако это кажется не совсем правильным - я получаю следующую ошибку:
- person ajp; 26.06.2013
удаление
r
из типа Proxy исправляет тип, но затем выдает другое о недопустимом объявлении экземпляра
- person ajp; 26.06.2013
@ajp Вам нужно добавить следующие два языковых расширения в начало файла:
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
- person Gabriel Gonzalez; 26.06.2013
этого было недостаточно в моем случае. В итоге мне понадобились MultiParamTypeClasses, FlexibleInstances и UndecidableInstances, чтобы заставить его работать.
- person ajp; 27.06.2013