我如何在Haskell中使用镜头来复制Python的枚举? [英] How would I use lens in Haskell to duplicate Python's enumerate?
问题描述
列表上的Python 枚举可以写成 zip [0 ..]
。我看着Control.Lens.Traversal和Control.Lens.Indexed,但我无法弄清楚如何使用镜头将其推广到任何合理的容器(我毫不犹豫地说Traversable)。
我在猜测 itraverse
或 itraverseOf
是关键。
如果您使用的是 FunctorWithIndex
实例的容器,那么您可以简单地使用 imap(,)
:
> imap(,)abc
[(0,'a'),(1,'b'),(2,'c')]
但是如果指数不是这个位置,这将不起作用:
>让m = Map.fromList [('a',foo),('b',bar),('c',foobar)])
> ('''('','')),('b',('b',bar)),('c',('你可以使用遍历
$ b $> / code>,这是一个索引遍历,索引是元素出现的顺序。这可以用于 Traversable
的任何事情。而不是 imap
使用 iover遍历
(与 imapOf $ c $相同c>但已被弃用): > iover遍历(,)abc
[(0,'a'),(1,'b'),(2,'c')]
> iover遍历(,)m
fromList [('a',(0,foo)),('b',(1,bar)),('c',(2,foobar ))]
Python's enumerate on lists can be written as zip [0..]
. I looked at Control.Lens.Traversal and Control.Lens.Indexed, but I couldn't figure out how to use lenses to generalize this to any reasonable container (I hesitate to say "Traversable").
I'm guessing itraverse
or itraverseOf
is key.
解决方案 If you're using a container that is an instance of FunctorWithIndex
then you can simply use imap (,)
:
> imap (,) "abc"
[(0,'a'),(1,'b'),(2,'c')]
But if the index isn't the position this won't work:
> let m = Map.fromList [('a', "foo"), ('b', "bar"), ('c', "foobar")])
> imap (,) m
fromList [('a',('a',"foo")),('b',('b',"bar")),('c',('c',"foobar"))]
Instead you can use traversed
, which is an indexed traversal where the index is the order the elements appear. This can be used for anything that's Traversable
. Instead of imap
use iover traversed
(which is the same as imapOf
but that's been deprecated):
> iover traversed (,) "abc"
[(0,'a'),(1,'b'),(2,'c')]
> iover traversed (,) m
fromList [('a',(0,"foo")),('b',(1,"bar")),('c',(2,"foobar"))]
这篇关于我如何在Haskell中使用镜头来复制Python的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!