2013-12-19 34 views
6
data Foo = Foo { 
    _bar :: Map String Integer 
} deriving (Eq, Ord, Read, Show, Data, Typeable) 

$(deriveSafeCopy 0 'base 'Foo) 

$(makeLenses ''Foo) 

Учитывая приведенный выше код я нахожусь под впечатлением, что это должно быть возможно сделать это:Как увеличить кислотное состояние?

addEntry :: String -> Update Foo() 
addEntry s = zoom bar $ modify $ insert s 0 

Но GHC будет жаловаться по линиям:

src/Backend.hs:39:20: 
    No instance for (Functor 
         (Control.Lens.Internal.Zoom.Zoomed (Update Foo)())) 

Любые идеи?

ответ

8

Control.Lens.Internal.Zoom.Zoomed - это семейство типов, которое описывает, какой контекст требуется во время zoom. Он выполняет некоторую специальную магию, как вы можете видеть в Control.Lens.Internal.Zoom module. Обычно пользователю zoom никогда не нужно будет видеть этот материал, если они увеличивают масштаб «типичного» стека трансформатора монады.

Update, будучи выполненным только как State под крышками, не имеет экземпляра масштабирования. Его реализация не экспортируется ни потому, что вы не можете написать свой собственный, хотя это было бы довольно тривиально, так как Update не использует монадные трансформаторы.

type instance Zoomed (Update x) = Focusing Identity 
+0

Так что, возможно, нет способа получить это (и подобные экземпляры) в какой-то пакет, например, «линзовое кислотное состояние»? – fho

+0

Это потребует еще нескольких подхалимных жонглирования модулей, возможно, «кислотного состояния внутреннего», от которого зависят и «кислотная кислота», и «линзовое кислотное состояние». –

+2

Стоит ли это того? Или есть способ обеспечить «Zoomed», не полагаясь на «объектив», как это возможно, с основными типами «Lens»? (Этот вопрос, вероятно, должен быть направлен непосредственно на экметта или сопровождающих кислотных состояний). – fho