我正在解析一个字符串,例如“xxxxyzz”,所以如果char是“x”,那么我将需要做一个输出并同时对列表进行更改。以下代码是
import Data.Char
output l = zipWith (+) rr ll
where
out = foldl
( \ (c,a) e ->
case c of
'x' -> chr c!!0 --output first element of the list
([1]++tail(c),a) ) -- add [1] to the c list
([0,0,0,0,0],[0,0,0,0,0])
(ll,rr) = out l
答案 0 :(得分:1)
你可以写(不推荐)一些像
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 Few Monads More(了解你的好事!)
你可以写一些像:
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上下文和数据;而不是直接IO output''
函数)。
您可以将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与monadic函数结合起来,比如“foldM”,有些像
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)
(日志数组相反)
答案 1 :(得分:0)
在Haskell中,如果不使用monad,就无法预测执行顺序。对于初学者,您可能希望尝试在do
的{{1}}块中进行一些测试,然后将其重写为单独的函数。
您可能希望熟悉Haskell中IO的概念: http://www.haskell.org/onlinereport/haskell2010/haskellch7.html#x14-1420007