IO()函数里面的putStr

putStr inside IO () function

如何在另一个IO()函数中调用IO()函数?我想打印到标准输出然后调用函数来做同样的事情。

例如,

p :: String -> IO ()
p [x] = putStr x
p xs = q xs

q :: String -> IO ()
q (x:xs) = putStr x ++ p xs

你的第一个问题是打字

p [x] = putStr x
{- putStr :: String -> IO ()
   x      :: Char, not a String
-}

q (x:xs) = putStr x ++ p xs
{- (++)     :: [a] -> [a] -> [a]
   putStr x :: IO (), not a list of anything.
-}

我们先看一下 q,因为它是 p 的结果。你把它分解成字符,所以你应该使用 putChar 而不是 putStr

此外,我们正在研究排序操作,因此我们应该使用 (>>)(>>=),具体取决于您是否需要结果。在这种情况下,结果是单位类型 (()) 的值,这是一个无用的结果,可以安全地忽略。

q :: String -> IO ()
q (x:xs) = putChar x >> p xs
{- or using `do` notation:
     q (x:xs) = do
       putChar x
       p xs
-}

p 同样可以更改为使用 putChar 而不是 putStr

p :: String -> IO ()
p [x] = putChar x
p xs  = q xs

但请注意,您没有在 pq 上匹配空列表。


关于这个时候你应该注意到用 putChar 代替 putStr 只是为了你可以将字符串分解为字符是一种落后的思维。 p = putStr 大功告成。但是,如果您坚持这种落后的思维方式:

import Control.Monad (foldM_, mapM_)

p = foldM_ (\_ x -> putChar x) ()
-- or
p = foldM_ ((putChar .) . flip const) ()
-- or
p = mapM_ putChar