duoids-0.0.1.0: src/Control/Duoidal/Either.hs
{-# LANGUAGE Safe #-}
-- |
-- Copyright: 2024 Greg Pfeil
-- License: AGPL-3.0-only WITH Universal-FOSS-exception-1.0 OR LicenseRef-commercial
--
-- Operations specific to failure duoids.
module Control.Duoidal.Either
( noteAccum,
)
where
import "base" Control.Applicative (Applicative, pure)
import "base" Control.Category ((.))
import "base" Data.Either (Either (Left))
import "base" Data.Function (($))
import "base" Data.Maybe (Maybe, maybe)
import "this" Control.Duoidal (Parallel (Parallel))
-- | Converts a maybe-returning function into a failed-input-accumulating one.
--
-- This is particularly useful for traversals, where you want to track _which_
-- elements of the traversal failed. E.g.,
--
-- > traverse safeHead :: t [a] -> Maybe (t a)
--
-- becomes
--
-- > traverse (noteAccum safeHead) :: t [a] -> Parallel (Either (NonEmpty a)) (t a)
noteAccum :: (Applicative f) => (a -> Maybe b) -> a -> Parallel (Either (f a)) b
noteAccum f a = Parallel . maybe (Left $ pure a) pure $ f a