如何使用lens获取子列表的头部?

Pau*_*-AG 5 haskell haskell-lens

我有一个价值观:

my :: [(A, Either B [C])]
Run Code Online (Sandbox Code Playgroud)

我想[(A, C)]镜头从中得到。结果项是来自my以下项的项:

  1. 元组中的第二项是Right [C]
  2. 此列表中Right [C]至少有 1 个项目,因此结果从中获取第一个(头)项目

我知道如何获得 ,[C]但我不知道如何获得[(A, C)]

K. *_*uhr 6

你要:

my ^.. each . runFold (second (Fold (_Right . _head)))
Run Code Online (Sandbox Code Playgroud)

这个想法是,这是一个从 中_Right . _head选择 a 的折叠。您可以使用from使其从 an 中选择一个。然而,要做到这一点,您需要使用具体化折叠(即,将其转换为带有实例的新类型),然后使用取消具体化。由此产生的折叠专门用于:CEither B [C](A, C)(A, Either B [C])secondControl.ArrowArrowFoldrunFold

runFold (second (Fold (_Right . _head))) :: Fold (A, Either B [C]) (A,C)
Run Code Online (Sandbox Code Playgroud)

它选择 的零个或一个实例(A,C),并且您可以将其组合起来each以折叠可遍历的容器,例如列表:

runFold (second (Fold (_Right . _head))) :: Fold [(A, Either B [C])] (A,C)
Run Code Online (Sandbox Code Playgroud)

(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)))
Run Code Online (Sandbox Code Playgroud)