英文:
How to get sublist's head using lens?
问题
我有一个值:
my :: [(A, Either B [C])]
我想使用 [lens][1] 从中获取 `[(A, C)]`。结果项是来自 `my` 的项,满足以下条件:
1. 元组中的第二项是 `Right [C]`
2. 此 `Right [C]` 中的列表至少有 1 项,所以结果从中获取第一个(head)项
我知道如何获取 `[C]`,但我不知道如何获取 `[(A, C)]`。
[1]: https://hackage.haskell.org/package/lens
英文:
I have a value:
my :: [(A, Either B [C])]
and I want to get [(A, C)]
from it using lens. The result items are items from my
that:
- the second item in tuples is
Right [C]
- the list in this
Right [C]
has at least 1 item, so the result get the first (head) item from it
I know how to get the [C]
but I don't know how to get [(A, C)]
.
答案1
得分: 6
以下是您要翻译的内容:
你想要:
my ^.. each . runFold (second (Fold (_Right . _head)))
这个想法是`_Right . _head`是一个从`Either B [C]`中选择`C`的折叠。您可以使用`Control.Arrow`中的`second`将其更改为从`(A, Either B [C])`中选择`(A, C)`。但是,为了实现这一点,您需要通过`Fold`将其实体化(即,将其转换为具有`Arrow`实例的新类型),然后使用`runFold`将其还原。生成的折叠专门用于:
runFold (second (Fold (_Right . _head))) :: Fold (A, Either B [C]) (A,C)
它选择零个或一个`(A,C)`的实例,并且您可以将其与`each`组合起来折叠可遍历的容器,例如列表:
runFold (second (Fold (_Right . _head))) :: Fold [(A, Either B [C])] (A,C)
以选择容器元素中的所有`(A,C)`。
示例代码:
import Control.Lens
import Control.Arrow
my :: [(Int, Either Double [Char])]
my = [(1, Right "apple"), (2, Left 1.5), (3, Right "bear"), (4, Right "")]
main = do
print $ my ^.. each . runFold (second (Fold (_Right . _head)))
希望这有所帮助。如果您需要进一步的解释或有其他问题,请随时提问。
英文:
You want:
my ^.. each . runFold (second (Fold (_Right . _head)))
The idea is that _Right . _head
is a fold that selects a C
from an Either B [C]
. You can make it select an (A, C)
from an (A, Either B [C])
, using second
from Control.Arrow
. However, to do this, you need to reify the fold (i.e., turn it into a newtype with an Arrow
instance) using Fold
and then unreify it with runFold
. The resulting fold specializes to:
runFold (second (Fold (_Right . _head))) :: Fold (A, Either B [C]) (A,C)
which selects either zero or one instances of (A,C)
, and you can compose it with each
to fold over a traversable container, like a list:
runFold (second (Fold (_Right . _head))) :: Fold [(A, Either B [C])] (A,C)
to select all of the (A,C)
from the container's elements.
Sample code:
import Control.Lens
import Control.Arrow
my :: [(Int, Either Double [Char])]
my = [(1, Right "apple"), (2, Left 1.5), (3, Right "bear"), (4, Right "")]
main = do
print $ my ^.. each . runFold (second (Fold (_Right . _head)))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论