对what the Comonad typeclass is in Haskell有所了解,我听说过Store comonad。但是看Control.Comonad.Store.Lazy,我真的不明白。这是什么意思?它是为了什么?我听说过Store = CoState,State Monad的双重身份。这是什么意思?
答案 0 :(得分:41)
鉴于商店的以下定义,
data Store s a = Store { peek :: s -> a, pos :: s }
我喜欢将Store
视为一个充满a
类型值的大型仓库。类型a
的每个值都被插入到由s
类型的索引值标记的位置。最后有一辆停在pos
位置的叉车。叉车可以从商店中使用extract
a
类型的价值,将价值从停车位置拉出来。您可以使用seek
将叉车移动到新的绝对位置,或使用seeks
将叉车移动到新的相对位置。要更新商店的所有值,请使用fmap
。最后extend f
与fmap
类似,除了f :: a -> a'
而不是f :: Store s a -> a'
我们extend
让更新功能不仅可以访问正在更新的值,还可以访问值位置和访问商店中其他所有值的值。换句话说,Store
使用该值加上其周围的上下文来执行更新。
更加计算机的类比是将{{1}}视为硬盘的大盘,其值存储在不同位置,加上停放在特定位置的头部。
答案 1 :(得分:35)
如果你看一下StoreT itself的定义,会容易得多。
您可以将其视为更大结构中的“位置”。例如,lens只是a -> Store b a
;您将获得 b 字段的值,并使用函数b -> a
将新值重新放回更大的上下文中。
以简化的非变压器形式考虑它:
data Store s a = Store (s -> a) s
instance Functor (Store s) where
fmap f (Store g s) = Store (f . g) s
instance Extend (Store s) where
duplicate (Store f s) = Store (Store f) s
instance Comonad (Store s) where
extract (Store f s) = f s
即。 duplicate
将s -> a
更改为s -> Store s a
,仅在替换值后返回“已更新”的位置,extract
将原始 a 恢复为将值重新放回更大的结构中。
就国家与国家的关系而言,你可以这样看待它:
type State s a = s -> (a, s)
type Store s a = (s -> a, s)