你可以写(不推荐)一些像
output'' :: String -> IO String
output'' = fmap reverse . foldM parseChar []
where parseChar xs 'x' = putStrLn "'x' to upper" >> return ('X':xs)
parseChar xs 'y' = putStrLn "'y' to 'W'" >> return ('W':xs)
parseChar xs x = putStrLn "no transform" >> return ( x :xs)
带输出
*Main> output'' "xyz"
'x' to upper
'y' to 'W'
no transform
"XWz"
但是,从For a Some Monads More (Learn You a Haskell for Great Good!)
你可以写一些像:
import Control.Monad.Writer
output :: String -> Writer [String] String
output [] = return []
output (x:xs) = do
xs' <- output xs
x' <- case x of
'x' -> tell ["'x' to upper"] >> return 'X'
'y' -> tell ["'y' to 'W'"] >> return 'W'
_ -> tell ["no transform"] >> return x
return (x':xs')
使用 monads 更加灵活,而使用 Writer 可以让你的代码变得纯粹(纯粹并且你可以控制如何处理 monadic 上下文和数据;而不是直接 IOoutput''
函数)。
您可以output
在不纯代码中使用函数作为
main = do
input <- getLine
let (result, logging) = runWriter $ output input
putStrLn $ "Result: " ++ result
putStrLn $ unlines logging
运行输出可能是
*Main> main
hxdynx
Result: hXdWnX
'x' to upper
no transform
'y' to 'W'
no transform
'x' to upper
no transform
您可以将 monad 与诸如“foldM”之类的 monadic 函数结合起来,有些像
output' :: String -> Writer [String] String
output' = fmap reverse . foldM parseChar []
where parseChar xs 'x' = tell ["'x' to upper"] >> return ('X':xs)
parseChar xs 'y' = tell ["'y' to 'W'"] >> return ('W':xs)
parseChar xs x = tell ["no transform"] >> return ( x :xs)
(对数数组颠倒)