对Comonads或Representable

时间:2018-03-31 07:19:50

标签: haskell lens comonad representable

以下是此问题的一个更具体的变体:Mutate only focus of Store Comonad?,以便不会一次提出多个问题。

是否有与Control.Lens兼容的镜头允许我与comonad(来自extract的值)的焦点或Store Comonad的索引/值进行交互({{1} })?

这里的镜头似乎有些用处,但我找不到合适的东西;任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:3)

Comonad没有给你任何回复comonad焦点的方法,所以你不能为Lens写一般extract。但是it is very easy to turn any old function into a Getter

extracted :: Comonad w => Getter (w a) a
extracted = to extract

当然,许多comonads 允许您写入焦点 - Store,正如您所提到的,但也包括(包括但不限于)Env,{{ 1}}和Traced

Identity

鉴于-- I suspect some of these laws are redundant: -- write id = id -- write f . write g = write (f . g) -- extract . write f = f . extract -- duplicate . write f = write (write f) . duplicate -- write (const (extract w)) w = w class Comonad w => ComonadWritable w where write :: (a -> a) -> w a -> w a instance ComonadWritable Identity where write f (Identity x) = Identity (f x) -- law-abiding "up to Eq" instance (Eq s, ComonadWritable w) => ComonadWritable (StoreT s w) where write f (StoreT w s) = StoreT (write g w) s where g k s' | s' == s = f (k s') | otherwise = k s' -- law-abiding "up to Eq" instance (Eq m, Monoid m, ComonadWritable w) => ComonadWritable (TracedT m w) where write f (TracedT w) = TracedT (write g w) where g k m | m == mempty = f (k m) | otherwise = k m instance ComonadWritable w => ComonadWritable (EnvT e w) where write f (EnvT e w) = EnvT e (write f w) ,可以轻松地为comonad的焦点构建ComonadWritable

Lens

关于效率的一个注释:focus :: ComonadWritable w => Lens' (w a) a focus = lens extract (\w x -> write (const x) w) StoreT的{​​{1}}实现构建了一系列函数,在向下的方式上进行了相等性检查,因此TracedT为O(n )write次呼叫的数量。由于您提到您正在使用extract comonad write,因此您可以实施一些巧妙的策略来批量编辑并将其频繁地重新设置为实际的Representable。或者,您可以将修改存储在w中(将w约束加强到Map)并在结果显示尚未编辑的元素时委托给基础Eq。我会把那部分留给你。