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)