Skip to content

Fix postmapM law by adding lifts #214

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 20, 2024
Merged

Conversation

Topsii
Copy link
Collaborator

@Topsii Topsii commented Nov 6, 2024

Adds lifts, which is similar to Control.Monad.Trans.Class.lift. You could define a Monad instance for FoldM such that

lifts (m >>= f) = lifts m >>= (lifts . f)
instance Monad (Fold a) where
  return = pure
  m >>= f = fold . f <$> m <*> list

instance Monad m => Monad (FoldM m a) where
  return = pure
  m >>= f = postmapM id $ foldM . f <$> m <*> generalize list

We already have hoists, which is similar to Control.Monad.Morph.hoist.
You can also define embeds and squashes, similar to Control.Monad.Morph.embed and Control.Monad.Morph.squash, respectively, satisfying (I believe)

embeds lifts = id

embeds f (lifts m) = f m
embeds :: Monad n => (forall x. m x -> FoldM n a x) -> FoldM m a b -> FoldM n a b
embeds f fld = squashes $ hoists f fld

squashes :: (Monad m) => FoldM (FoldM m a) a b -> FoldM m a b
squashes (FoldM step begin done) = join $ FoldM step' begin' done'
  where
    step' fmax a = pure $ do
      x <- fmax
      step x a
    begin' = pure begin
    done' fmax = pure $ do
      x <- fmax
      done x

As I understand it, these Fold(M) Monad instances are not desirable because they do not stream in constant memory. Hence we only define lifts and use it to fix a law of postmapM.

@Topsii Topsii mentioned this pull request Nov 6, 2024
@Gabriella439 Gabriella439 merged commit 2ebc619 into Gabriella439:main Dec 20, 2024
5 checks passed
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Jan 31, 2025
1.4.18

- Add [`lifts`](Gabriella439/foldl#214)
- Add [`nest`](Gabriella439/foldl#215) for `Fold1`
- Add [`Choice`, `Closed`, `Cosieve`, `Extend`, `Semigroupoid`, `Category`, `Strong`, `Arrow` and `ArrowChoice`](Gabriella439/foldl#215) instances for `Fold1`
- Add [`Closed`](Gabriella439/foldl#215) instance for `Fold`
- [Define `stimes` from `EndoM`'s Semigroup instance for 0](Gabriella439/foldl#217)

1.4.17

- Add [Fold1 utilities](Gabriella439/foldl#212): `purely`, `purely_`, `premap`, `handles`, `foldOver`, `folded1`
- Add pattern synonym [`Fold1_`](Gabriella439/foldl#212) that makes the initial, step and extraction functions explicit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants