3

mapMアキュムレータを通過しながら通過できるものが欲しいです。私は思いついた:

import Control.Applicative
import Data.Traversable
import Control.Monad.State

mapAccumM :: (Applicative m, Traversable t, MonadState s m)
             => (s -> a -> m (s, b)) -> s -> t a -> m (t b)
mapAccumM f acc0 xs = put acc0 >> traverse g xs
  where
    g x = do
      oldAcc <- get
      (newAcc, y) <- f oldAcc x
      put newAcc
      return y

Stateこれはモナドなしでどのように行うことができますか?

4

1 に答える 1

2

roconnorは#haskellで私のためにこれに答えました

これで問題は解決しますが、アキュムレータが最初の要素ではなく、タプルの2番目の要素で返されることに注意してください。

mapAccumM :: (Monad m, Functor m, Traversable t) => (a -> b -> m (c, a)) -> a -> t b -> m (t c)
mapAccumM f = flip (evalStateT . (Data.Traversable.traverse (StateT . (flip f))))

または、アキュムレータを返す場合:

mapAccumM' :: (Monad m, Functor m, Traversable t) => (a -> b -> m (c, a)) -> a -> t b -> m (t c, a)
mapAccumM' f = flip (runStateT . (Data.Traversable.traverse (StateT . (flip f))))
于 2012-07-25T15:20:45.283 に答える