tipos por monadas listas intensionales guardarlo functores funciones definir datos comprension como comandos ciclos agregar haskell functional-programming monads monad-transformers

por - ¿Cómo combino las mónadas en Haskell?



listas intensionales haskell (3)

¿En qué sentido quieres combinar las mónadas?

f :: Int -> IO (Maybe Int) f x = do putStrLn "Hello world!" return $ if x == 0 then Nothing else Just x

Puede ser evaluado para:

[1 of 1] Compiling Main ( maybe-io.hs, interpreted ) Ok, modules loaded: Main. *Main> f 0 Hello world! Nothing *Main> f 3 Hello world! Just 3

Particularmente, necesito poder combinar la mónada CGI con la mónada IO, pero un ejemplo de cómo combinar la mónada IO con la mónada Maybe podría ser aún mejor ...


No dice exactamente cómo desea combinar IO y Maybe , pero supongo que tiene muchas funciones que devuelven IO (Maybe a) que desea combinar fácilmente. Básicamente, usted quiere tratar IO (Maybe a) como un tipo separado con su propia instancia de Monad :

newtype IOMaybe a = IOM (IO (Maybe a)) -- "unpack" a value of the new type runIOMaybe :: IOMaybe a -> IO (Maybe a) runIOMaybe (IOM a) = a instance Monad IOMaybe where -- bind operator (IOM ioa) >>= f = IOM $ do a <- ioa case a of Nothing -> return Nothing Just v -> runIOMaybe (f v) -- return return a = IOM (return (Just a)) -- maybe also some convenience functions returnIO :: IO a -> IOMaybe a returnIO ioa = IOM $ do v <- ioa return (Just v) returnMaybe :: Maybe a -> IOMaybe a returnMaybe ma = IOM (return ma)

Con esto, puede usar la opción -Notation para combinar funciones que devuelven IO (Maybe a) , IO a o Maybe a :

f1 :: Int -> IO (Maybe Int) f1 0 = return Nothing f1 a = return (Just a) main = runIOMaybe $ do returnIO $ putStrLn "Hello" a <- returnMaybe $ Just 2 IOM $ f1 a return ()

En general, algo que combina y modifica las mónadas como esta se denomina transformador de mónada , y GHC viene con un package que incluye transformadores de mónada para casos comunes. Si hay algo en esta biblioteca de transformadores de mónada que se adapte a su escenario, depende de cómo exactamente desea combinar Maybe y IO.


Supongo que desea utilizar la mónada Maybe para la terminación anticipada (como break o return en C).

En ese caso, debe usar MaybeT del paquete MaybeT ( cabal install MaybeT ).

main = do runMaybeT . forever $ do liftIO $ putStrLn "I won''t stop until you type pretty please" line <- liftIO getLine when ("pretty please" == line) mzero return ()

MaybeT es una versión de la mónada transformadora de la mónada.

Los transformadores de mónada "agregan funcionalidad" a otras mónadas.