MonadSum

Oct 05, 2012 21:54

Подумалось мне про трансформеры монад, что если у нас есть натуральные преобразования из монад m и n в некую монаду l, то l - это их сумма, если добавить ещё и обратную функцию. Т.е. при наличии натурального преобразования m => t и n => t можем получить и m+n => t.

Попробовал я это представить прямо в таком виде:

data MonadSum m n a = MonadSum { monadSum :: forall t. (Monad t) => (forall b. m b -> t b) -> (forall c. n c -> t c) -> t a }

И вот, что получилось:

maybeIO :: Maybe a -> StateT s IO a maybeIO Nothing = error "Nothing" maybeIO (Just v) = return v eitherIO :: Either String a -> StateT s IO a eitherIO (Left e) = error e eitherIO (Right v) = return v stateIO :: State s a -> StateT s IO a stateIO act = StateT $ return . runState act bla :: MonadSum Maybe (MonadSum (Either String) (State Int)) String bla = do n <- liftR $ liftR get case n of 0 -> liftL Nothing 1 -> liftR $ liftL $ Left "Error" 2 -> liftR $ liftL $ Right "Ok!" _ -> do liftR $ liftR $ put (n `div` 2) s <- bla return $ show n ++ s testBla :: Int -> IO String testBla = evalStateT $ unlift maybeIO (unlift eitherIO stateIO) bla
Запуск:

*MonadSum> testBla 0 *** Exception: Nothing *MonadSum> testBla 1 *** Exception: Error *MonadSum> testBla 2 "Ok!" *MonadSum> testBla 3 *** Exception: Error *MonadSum> testBla 4 "4Ok!" *MonadSum> testBla 8 "84Ok!" *MonadSum> testBla 7 *** Exception: Error

Полный код тут.

monad, fp, теория категорий, haskell

Previous post Next post
Up