What is the author's monad and audition point?

I studied monads in the book learnyouahaskell . After reading about the writerโ€™s monad, I decided to check out the Control.Monad.Writer.Class documentation .

There I saw that they also implemented functions listenand pass, but I could not understand what they are used for. Can someone give me a good example so that I can understand how to use listenand pass?

+4
source share
2 answers

Here is the code from Control.Monad.Trans.Writer.Strictthat defined listenand pass:

listen :: (Monoid w, Monad m) => WriterT w m a -> WriterT w m (a, w)
listen m = WriterT $ do
    (a, w) <- runWriterT m
    return ((a, w), w)

pass :: (Monoid w, Monad m) => WriterT w m (a, w -> w) -> WriterT w m a
pass m = WriterT $ do
    ((a, f), w) <- runWriterT m
    return (a, f w)

WriterT , Writer , Writer type Writer w = WriterT w Identity, Identity monad (<- >>=) , , :

listen :: (Monoid w) => Writer w a -> Writer w (a, w)
listen m = Writer $
    let (a, w) = runWriter m
    in ((a, w), w)

pass :: (Monoid w) => Writer w (a, w -> w) ->ใ€€Writer w a
pass m = Writer $
    let ((a, f), w) = runWriter m
    in (a, f w)

, listen , Writer Writer, pass Writer.

, Writer [String] , :

deleteOn :: (Monoid w) => (w -> Bool) -> Writer w a -> Writer w a
deleteOn p m = pass $ do
    (a, w) <- listen m
    if p w
        then return (a, id)
        else return (a, const mempty)

-- Or pass alone
deleteOn' :: (Monoid w) => (w -> Bool) -> Writer w a -> Writer w a
deleteOn' p m = pass $ do
    a <- m
    return (a, (\w -> if p w then mempty else w))

logTwo :: Writer [String] ()
logTwo = do
    deleteOn ((> 5) . length . head) $ tell ["foo"]
    deleteOn ((> 5) . length . head) $ tell ["foobar"]
{-
*Main> runWriter logTwo
((),["foo"])
-}
+6

Writer , , , ( "" ) , execWriter runWriter. , listen , - - , , , pass .

, WriterT :

import Control.Monad.Writer

-- Monad stack for the application uses IO, wrapped in a logging WriterT
type App a = WriterT [String] IO a

-- utility to write to the log
logMsg :: String -> App ()
logMsg msg = tell [msg]

-- gets an Int from user input (and logs what it does)
getInt :: App Int
getInt = do
    logMsg "getting data"
    n <- liftIO getLine
    logMsg $ "got line: " ++ show n
    return . read $ n

-- application logic that uses getInt and increments the result by 1
app :: App Int
app = do
    n <- getInt
    return $ n + 1

-- main code runs the application and prints the log
main = do
    (res, logs) <- runWriterT app
    print $ "Result = " ++ show res
    putStrLn "Log: "
    mapM_ putStrLn logs

, - , app, , getInt . listen:

app :: App Int
app = do
    (n, logs) <- listen getInt
    let numLogLines = length logs
    logMsg $ "getInt logged " ++ show numLogLines ++ " lines"
    return $ n + 1
+3

Source: https://habr.com/ru/post/1624614/


All Articles