haskell 如何使用透镜获取子列表的头部?

dhxwm5r4  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(86)

我有一个价值观:

my :: [(A, Either B [C])]

我想用lens得到[(A, C)]。结果项是来自my的以下项:
1.元组中第二项是Right [C]
1.这个Right [C]中的列表至少有1个项目,所以结果从它得到第一个(头)项目
我知道如何获得[C],但我不知道如何获得[(A, C)]

yhived7q

yhived7q1#

您需要:

my ^.. each . runFold (second (Fold (_Right . _head)))

这个想法是_Right . _head是一个从Either B [C]中选择C的折叠。您可以使用second from Control.Arrow(A, Either B [C])中选择(A, C)。但是,要做到这一点,您需要使用Fold将fold具体化(即,将其转换为具有Arrow示例的newtype),然后使用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)))

相关问题