Haskell Lens.Internal.Indexed如何连接到键控容器?

Haskell Lens.Internal.Indexed如何连接到键控容器?,haskell,traversal,haskell-lens,Haskell,Traversal,Haskell Lens,为了进一步了解这一思想,可以将函数应用于可通过其索引遍历的对象的任何元素 import Control.Monad.State updateAt :: forall a. Int -> (a -> a) -> [a] -> [a] updateAt i f = flip evalState [0..] . traverse g where g :: a -> State [Int] a g x = do js <- get

为了进一步了解这一思想,可以将函数应用于可通过其索引遍历的对象的任何元素

import Control.Monad.State

updateAt :: forall a. Int -> (a -> a) -> [a] -> [a]
updateAt i f = flip evalState [0..] . traverse g
  where
    g :: a -> State [Int] a
    g x = do
        js <- get
        case js of
            [ ]      -> error ""
            (j: js') -> do
                put js'
                if j == i
                   then return (f x)
                   else return x
我承认这有点过头了。我喜欢“可转位”的发音——它一定很有用。但这似乎也是哈斯克尔有史以来最难写的一篇。我知道,
Conjoined
是一种高级的profunctor,所以基本上。。。函数?我不确定它可能是什么,以及这一切是如何连接到键控容器的


这适用于我的问题吗?这是干什么用的?我如何理解它呢?

可索引的ip实际上只是指“
p
(>)
索引的I
索引的iab=I->a->b
)”。
lens
包构建在一个非常抽象的类塔上,使所有内容都非常通用。具体地说,它不使用函数,而是尝试使用一般的profunctor,但尝试处理索引基本上会导致整个过程崩溃(非常嘈杂,正如您所看到的),只是“profunctor要么是
(>)
,要么是
索引的i

在任何情况下,您都不关心可索引的
。您所说的“索引”是
元素的参数。
IndexedTraversable
中的“索引”是一个“结果”,由
IndexedTraversable
返回的每个元素也有与其关联的索引。在这里,它只是返回您再次传入的参数,以防其他人想要得到它。你没有。要恢复
updateAt
,只需将
元素的返回值传递给
,将
p
专门化为
(>)
,并丢弃重复的索引:

updateAt :: Traversable t => Int -> (a -> a) -> t a -> t a
updateAt = over . element
-- updateAt i f = over (element i) f
-- "over element i do f"
我认为
over
相当“低级”


一般来说,我假设“带索引的
Traversable
操作”的“门户”是
traversed
,基本上是“
traverse
(当您将其
p
专门化为
(>)
elements=elementsOf traverse=elementsOf traversed
element=elementOf traverse=elementsOf traversed
只需过滤特定索引即可

可索引的ip
实际上只是意味着“
p
要么是
(>)
要么是
索引的i
索引的iab=i->a->b
)”。
lens
包构建在一个非常抽象的类塔上,使所有内容都非常通用。具体地说,它不使用函数,而是尝试使用一般的profunctor,但尝试处理索引基本上会导致整个过程崩溃(非常嘈杂,正如您所看到的),只是“profunctor要么是
(>)
,要么是
索引的i

在任何情况下,您都不关心可索引的
。您所说的“索引”是
元素的参数。
IndexedTraversable
中的“索引”是一个“结果”,由
IndexedTraversable
返回的每个元素也有与其关联的索引。在这里,它只是返回您再次传入的参数,以防其他人想要得到它。你没有。要恢复
updateAt
,只需将
元素的返回值传递给
,将
p
专门化为
(>)
,并丢弃重复的索引:

updateAt :: Traversable t => Int -> (a -> a) -> t a -> t a
updateAt = over . element
-- updateAt i f = over (element i) f
-- "over element i do f"
我认为
over
相当“低级”


一般来说,我假设“带索引的
Traversable
操作”的“门户”是
traversed
,基本上是“
traverse
(当您将其
p
专门化为
(>)
elements=elementsOf traverse=elementsOf traversed
element=elementOf traverse=elementsOf traversed
只需过滤特定索引即可

over
是一个非常高的级别。我所说的“低水平”有点像:>>>“猫”^@。。索引(折叠折叠)[(0,'c'),(1,'a'),(2,'t'),(3,'c'),(4,'a'),(5,'t')]当我看
折叠的
遍历的
时,它是索引的
连体的
再次:折叠=连体的(foldring foldr)(ifoldring ifoldr)遍历=连体的遍历(索引遍历)我仍然不明白这意味着什么。也许还有另一个问题?@IgnatInsarov这没有任何意义。这是一个实现细节,而不是一个表示
conjoined大致上是“当使用这个遍历索引或非索引时,这里是完全独立的实现,当GHC有足够的信息来确定哪个是正确的版本时,有所有必要的机制使GHC内联。”
over
是最高级的。我所说的“低水平”有点像:>>>“猫”^@。。索引(折叠折叠)[(0,'c'),(1,'a'),(2,'t'),(3,'c'),(4,'a'),(5,'t')]当我看
折叠的
遍历的
时,它是索引的
连体的
再次:折叠=连体的(foldring foldr)(ifoldring ifoldr)遍历=连体的遍历(索引遍历)我仍然不明白这意味着什么。也许还有另一个问题?@IgnatInsarov这没有任何意义。这是一个实现细节,而不是一个表示
conjoined
大致上是“当使用这个遍历索引或非索引时,这里是完全独立的实现,当它有足够的信息来确定哪个是索引时,有所有必要的机制使GHC内联成为正确的版本。”
-- basically
over :: ((a -> Identity b) -> (s -> Identity t)) -> (a -> b) -> (s -> t)
over setter f = runIdentity . setter (Identity . f)
-- I think even over = coerce would be valid
-- meaning it's actually just an identity function
-- and that updateAt = element (but with the type changed)