使用镜头按索引访问矢量元素
Accessing vector element by index using lens
我正在寻找一种使用镜头库引用矢量元素的方法...
让我尝试使用我的代码的简化示例来解释我要实现的目标。
我在这个 monad 转换器堆栈中工作(其中 StateT 是重点,其他一切都不重要)
newtype MyType a = MyType (StateT MyState (ExceptT String IO) a)
MyState 有很多字段,但其中一个是客户端向量,这是我定义的数据类型:
data MyState = MyState { ...
, _clients :: V.Vector ClientT
}
每当我需要访问我的一个客户时,我倾向于这样做:
import Control.Lens (use)
c <- use clients
let neededClient = c V.! someIndex
... -- calculate something, update client if needed
clients %= (V.// [(someIndex, updatedClient)])
现在,这就是我要找的东西:我希望我的函数接收到我感兴趣的客户端的 "reference" 并使用它(从 State 检索它,如果需要更新它).
为了弄清楚我的意思,这里有一个片段(即使是伪代码也不会编译):
...
myFunction (clients.ix 0)
...
myFunction clientLens = do
c <- use clientLens -- I would like to access a client in the vector
... -- calculate stuff
clientLens .= updatedClient
基本上,我想从 Lens 库中向 myFunction 传递一些东西(我不知道我在这里传递的是什么...... Lens?遍历?获取?其他一些东西?)这将使我能够指出在我的 StateT 中保存的向量中的特定元素处。有可能吗?目前,在使用 "clients.ix 0" 时出现错误,提示我的 ClientT 不是 Monoid 的实例。
这是我所拥有的一个非常简单的版本。为了回答问题 "why I need it this way" 需要更多的解释。我很感兴趣是否可以传递这个 "reference" 它将指向我的向量中保存在 State 中的某个元素。
clients.ix 0
是遍历。特别是,遍历是设置器,因此设置和修改应该可以正常工作:
clients.ix 0 .= updatedClient
您的问题出在 use
上。因为遍历不一定只包含一个值,所以当您 use
遍历(或在其上使用其他 getter 函数)时,它会合并所有值,假设它们属于 Monoid
类型。
特别是,
use (clients.ix n)
想要return mempty
如果n
超出范围。
相反,您可以使用 preuse
函数,它丢弃遍历的 first 目标以外的所有目标(或更一般地说,折叠),并将其包装在Maybe
。例如
Just c <- preuse (clients.ix n)
请注意,如果 n
超出范围,这将给出模式匹配错误,因为 preuse
returns Nothing
那么。
我正在寻找一种使用镜头库引用矢量元素的方法...
让我尝试使用我的代码的简化示例来解释我要实现的目标。
我在这个 monad 转换器堆栈中工作(其中 StateT 是重点,其他一切都不重要)
newtype MyType a = MyType (StateT MyState (ExceptT String IO) a)
MyState 有很多字段,但其中一个是客户端向量,这是我定义的数据类型:
data MyState = MyState { ...
, _clients :: V.Vector ClientT
}
每当我需要访问我的一个客户时,我倾向于这样做:
import Control.Lens (use)
c <- use clients
let neededClient = c V.! someIndex
... -- calculate something, update client if needed
clients %= (V.// [(someIndex, updatedClient)])
现在,这就是我要找的东西:我希望我的函数接收到我感兴趣的客户端的 "reference" 并使用它(从 State 检索它,如果需要更新它).
为了弄清楚我的意思,这里有一个片段(即使是伪代码也不会编译):
...
myFunction (clients.ix 0)
...
myFunction clientLens = do
c <- use clientLens -- I would like to access a client in the vector
... -- calculate stuff
clientLens .= updatedClient
基本上,我想从 Lens 库中向 myFunction 传递一些东西(我不知道我在这里传递的是什么...... Lens?遍历?获取?其他一些东西?)这将使我能够指出在我的 StateT 中保存的向量中的特定元素处。有可能吗?目前,在使用 "clients.ix 0" 时出现错误,提示我的 ClientT 不是 Monoid 的实例。
这是我所拥有的一个非常简单的版本。为了回答问题 "why I need it this way" 需要更多的解释。我很感兴趣是否可以传递这个 "reference" 它将指向我的向量中保存在 State 中的某个元素。
clients.ix 0
是遍历。特别是,遍历是设置器,因此设置和修改应该可以正常工作:
clients.ix 0 .= updatedClient
您的问题出在 use
上。因为遍历不一定只包含一个值,所以当您 use
遍历(或在其上使用其他 getter 函数)时,它会合并所有值,假设它们属于 Monoid
类型。
特别是,
use (clients.ix n)
想要return mempty
如果n
超出范围。
相反,您可以使用 preuse
函数,它丢弃遍历的 first 目标以外的所有目标(或更一般地说,折叠),并将其包装在Maybe
。例如
Just c <- preuse (clients.ix n)
请注意,如果 n
超出范围,这将给出模式匹配错误,因为 preuse
returns Nothing
那么。