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)))
1条答案
按热度按时间yhived7q1#
您需要:
这个想法是
_Right . _head
是一个从Either B [C]
中选择C
的折叠。您可以使用second
fromControl.Arrow
从(A, Either B [C])
中选择(A, C)
。但是,要做到这一点,您需要使用Fold
将fold具体化(即,将其转换为具有Arrow
示例的newtype),然后使用runFold
将其取消具体化。生成的折叠专门用于:它选择
(A,C)
的零个或一个示例,您可以将其与each
组合以折叠在可遍历容器上,如列表:从容器的元素中选择所有
(A,C)
。示例代码: