2011-12-20 18 views

risposta

18

Se si desidera stampare il risultato della funzione foo :: Int -> IO String (per esempio), si può fare

main = do 
    str <- foo 12 
    putStrLn str 

o senza il fai-notazione

main = foo 12 >>= putStrLn. 

Il fai-notazione è zucchero sintattico per il secondo, che utilizza il fondamentale combinatore (>>=), che ha il tipo

(>>=) :: Monad m => m a -> (a -> m b) -> m b 

IO è un'istanza della classe Monad, quindi è possibile utilizzarla qui.

foo :: Int -> IO String 
foo 12 :: IO String 

putStrLn :: String -> IO() 

(foo 12) >>= putStrLn :: IO() 
6

Come si fa a stampare l'output di una funzione che restituisce una stringa IO al stdout?

Bene, vediamo. Ecco una funzione che restituisce una stringa IO: (! Ma una funzione comunque)

dumbFunction :: a -> IO String 
dumbFunction x = getLine 

dumbFunction è una funzione muto. Ignora il suo input e quindi restituisce getLine, che ha il tipo IO String.

Quindi mi dici, come si stampa getLine :: IO String? La risposta è che non lo fai! Questo è ciò che chiamiamo "azione IO". Si noti che un'azione IO è non una funzione, perché fa non prendere input. (Tuttavia, le azioni IO potrebbero acquisire input da, beh, le operazioni di IO come la lettura stdin, come getLine fa. Ma non è considerata una "funzione", perché non accetta alcun input tradizionale)

Così, invece di stampare l'azione stessa, probabilmente si desidera eseguire l'azione e quindi stampare il risultato. Questo può essere fatto come descritto da Daniel Fischer (con <-, che può essere considerato come l'operatore "run").