VoidEx (voidex) wrote,
VoidEx
voidex

  • Music:

MonadSum

Подумалось мне про трансформеры монад, что если у нас есть натуральные преобразования из монад 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


Полный код тут.
Tags: fp, haskell, monad, теория категорий
Subscribe
  • Post a new comment

    Error

    default userpic
    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 14 comments