Haskell 如何使用镜头库进行snoc?

Haskell 如何使用镜头库进行snoc?,haskell,haskell-lens,Haskell,Haskell Lens,我在尝试与爱德华兹lenslibrary合作时被难住了。在状态上下文中,我尝试snoc在向量的末尾添加一些内容: data Foo = Foo { _vec :: Vector Int } makeLenses ''Foo testCons x = vec <>= singleton x data Foo=Foo{ _向量:向量整数 } 美孚 testCons x=vec=singleton x 虽然这样做有效,但我想使用[cons][2],但我不知道如何使用。文档中提到

我在尝试与爱德华兹
lens
library合作时被难住了。在状态上下文中,我尝试
snoc
在向量的末尾添加一些内容:

data Foo = Foo {
  _vec :: Vector Int
}

makeLenses ''Foo

testCons x = vec <>= singleton x
data Foo=Foo{
_向量:向量整数
}
美孚
testCons x=vec=singleton x
虽然这样做有效,但我想使用
[cons][2]
,但我不知道如何使用。文档中提到了
[0,1,2]|>3==[0,1,2,3]
,但我不知道如何在状态上下文中实现这一点。

使用(%=)组合器可以将函数应用于镜头的目标;你想要什么

stateSnoc :: MonadState Foo m => Int -> m ()
stateSnoc x = vec %= (|> x)

snoc
似乎是为了方便起见从原始的
Prism
定义的普通函数,即
\u snoc

那么为什么不使用一个普通的
MonadState
函数呢


你会大量添加元素吗?如果是这样的话,你应该改用a。考虑到一个向量是O(n),但对于一个序列是O(1);另一方面,与向量的O(1)相比,序列具有O(logn)随机访问。@Kata-yay。。。我知道:-)。。。我可能应该在真正的代码中使用
Foo f a=Foo(f a)
。我必须将其与
zoom
结合起来,以关注嵌套的条目。。。但是有没有办法直接使用
\u Snoc
?比如
foo。vec_Snoc.=bar
?Snoc棱镜的默认方向是从一个集合到一对
(集合减去最后一个元素,最后一个元素)
。但是您可以使用
review
函数“扭转局面”,编写类似
review的代码(['b'],'a')
。这几乎就是snoc的定义,但没有经过编译。但是要注意,
review\u Snoc
不是一个镜头,而是一个常规功能。更正:
review
的结果适用于任何
monader
。嗯。。。情况没有好转:)。。。我猜是有某种镜头/设置器指向容器的“后面”。@Florian我怀疑是否有
设置器可以用于附加到容器中。
Setters
必须遵守的一条(相当直观的)法则是,用两个不同的值设置两次等于用最后一个值只设置一次。但是在某物后面加上“a”和“b”并不等于只加上“b”!我怀疑附加和解构本质上类似于
Prism
。虽然这会起作用,但我缺少了其他
lens
函数的一些优雅。你说的“优雅”是什么意思?我期待着类似
vec+=x
的东西。虽然这当然是为
Num
保留的。我想这是你将要得到的最漂亮的。没有一个二传手指向最后一个元素的后面,因为,好吧,那是什么意思?那里永远不会有任何有趣的值。接受是因为它显然是正确的。但我建议也读另一个答案。
runState (modify $ flip snoc 'a') ['b']
-- ((),"ba")