You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If we take a list and imagine extending it to fill all missing locations (locations past the end of the list) with a default value, e.g. like xs ++ repeat defx, then such constructions can be losslessly zipped together:
Of course if we have xs ++ repeat defx we can no longer take it apart into the "main" part and the "filler" part. Instead we may want do bookkeeping to keep them separate like this:
dataFillLista=FillList [a] aderiving (Functor)
instanceApplicativeFillListwherepure x =FillList[] x
liftA2 f (FillList xs defx) (FillList ys defy)
=FillList (alignWith (uncurry f . fromThese defx defy) xs ys) (f defx defy)
This easily generalizes to an arbitrary Align:
dataFillfa=Fill (fa) aderiving (Functor)
instanceAlignf=>Applicative (Fillf) wherepure x =Fill nil x
liftA2 f (Fill xs defx) (Fill ys defy)
=Fill (alignWith (uncurry f . fromThese defx defy) xs ys) (f defx defy)
Thus we have an Applicative that in a certain sense losslessly captures the Align operation:
The fromJust there is unfortunate but it's valid (it ultimately relies on functoriality and the fact that uncurry (align @Maybe) . fromThese Nothing Nothing . bimap Just Just = Just). (If anyone has any clever ideas regarding how to get rid of it, I'm all ears).
Generalizing to zipping arbitrarily many structures we obtain:
where the function returns Nothing in case all of the inputs were Nothing. This is significant for e.g. t ~ NonEmpty. But if we're implementing sequenceL from catMaybes then the catMaybes is never invoked with a container full of Nothing's (for a reason similar to the alignWith' case), so we can use catMaybes = fromJust . almostCatMaybes. This leads us to the final remarkable fact:
The complete behavior of sequenceL can be recovered from its Maybe specialization:
If we take a list and imagine extending it to fill all missing locations (locations past the end of the list) with a default value, e.g. like
xs ++ repeat defx
, then such constructions can be losslessly zipped together:Of course if we have
xs ++ repeat defx
we can no longer take it apart into the "main" part and the "filler" part. Instead we may want do bookkeeping to keep them separate like this:This easily generalizes to an arbitrary
Align
:Thus we have an Applicative that in a certain sense losslessly captures the
Align
operation:The
fromJust
there is unfortunate but it's valid (it ultimately relies on functoriality and the fact thatuncurry (align @Maybe) . fromThese Nothing Nothing . bimap Just Just = Just
). (If anyone has any clever ideas regarding how to get rid of it, I'm all ears).Generalizing to zipping arbitrarily many structures we obtain:
If
t
supports acatMaybes
operation, i.e. isFilterable
, we can turn intof (t a)
, and this operation in fact coincides withsequenceL
:Witherable
is essentiallyTraversable
+Filterable
, so everyWitherable
is aCrosswalk
. QuickCheck agrees:An even more remarkable result is that every
Crosswalk
is almost aFilterable
:where the function returns
Nothing
in case all of the inputs wereNothing
. This is significant for e.g.t ~ NonEmpty
. But if we're implementingsequenceL
fromcatMaybes
then thecatMaybes
is never invoked with a container full ofNothing
's (for a reason similar to thealignWith'
case), so we can usecatMaybes = fromJust . almostCatMaybes
. This leads us to the final remarkable fact:The complete behavior of
sequenceL
can be recovered from itsMaybe
specialization:The text was updated successfully, but these errors were encountered: