могу ли я сделать StateP из Control.Proxy экземпляром MonadState?

Я изменяю некоторый код, который раньше выполнялся внутри монады StateT, чтобы он выполнялся внутри монады StateP из Control.Proxy. Однако для части моего кода (например, для оператора %= из Control.Lens) требуется экземпляр MonadState. Безопасно ли для меня просто добавить такой экземпляр? Это похоже на то, что наиболее правильно обрабатывается библиотекой (в данном случае Control.Proxy).


person ajp    schedule 23.06.2013    source источник


Ответы (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
comment
огромное спасибо! однако это кажется не совсем правильным - я получаю следующую ошибку: - person ajp; 26.06.2013
comment
удаление r из типа Proxy исправляет тип, но затем выдает другое о недопустимом объявлении экземпляра - person ajp; 26.06.2013
comment
@ajp Вам нужно добавить следующие два языковых расширения в начало файла: {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-} - person Gabriel Gonzalez; 26.06.2013
comment
этого было недостаточно в моем случае. В итоге мне понадобились MultiParamTypeClasses, FlexibleInstances и UndecidableInstances, чтобы заставить его работать. - person ajp; 27.06.2013