Foldl traverses with State, foldr traverses with anything

It’s also possible to make the Haskell version a lot cleaner without adding more sugar:

findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
findM p xs = runEarlyT do
  for_ xs \x -> do
    b <- lift (p x)
    when b (earlyReturn (Just x))
  pure Nothing

See the previous discussion: The ICFP'22 playlist has been published to YouTube - #19 by jaror

Edit: Here’s how one could write !?:

(!?) :: [a] -> Int -> Maybe a
xs !? n = runEarly do
  when (n < 0) $ earlyReturn Nothing
  flip evalStateT n do
    for_ xs \x -> do  
      k <- get
      when (k == 0) $ lift $ earlyReturn $ Just x
      put (k - 1)
  pure Nothing

And maybe it’s possible to clean it up more.

2 Likes