There are lots of functors that look like containers (lists, sequences, maps, etc.), and many others that don\'t (state transformers, IO
, parsers, etc.). I\'ve
Well, with the help of universe, one could potentially write Foldable
and Traversable
instances for state transformers over finite state spaces. The idea would be roughly similar to the Foldable
and Traversable
instances for functions: run the function everywhere for Foldable
and make a lookup table for Traversable
. Thus:
import Control.Monad.State
import Data.Map
import Data.Universe
-- e.g. `m ~ Identity` satisfies these constraints
instance (Finite s, Foldable m, Monad m) => Foldable (StateT s m) where
foldMap f m = mconcat [foldMap f (evalStateT m s) | s <- universeF]
fromTable :: (Finite s, Ord s) => [m (a, s)] -> StateT s m a
fromTable vs = StateT (fromList (zip universeF vs) !)
float :: (Traversable m, Applicative f) => m (f a, s) -> f (m (a, s))
float = traverse (\(fa, s) -> fmap (\a -> (a, s)) fa)
instance (Finite s, Ord s, Traversable m, Monad m) => Traversable (StateT s m) where
sequenceA m = fromTable <$> traverse (float . runStateT m) universeF
I'm not sure whether this makes sense. If it does, I think I would be happy to add it to the package; what do you think?