简体   繁体   中英

How withFile is implemented in haskell

Following a haskell tutorial , the author provides the following implementation of the withFile method:

withFile' :: FilePath -> IOMode -> (Handle -> IO a) -> IO a  
withFile' path mode f = do  
    handle <- openFile path mode   
    result <- f handle  
    hClose handle  
    return result  

But why do we need to wrap the result in a return ? Doesn't the supplied function f already return an IO as can be seen by it's type Handle -> IO a ?

You're right: f already returns an IO , so if the function were written like this:

withFile' path mode f = do  
    handle <- openFile path mode   
    f handle

there would be no need for a return. The problem is hClose handle comes in between, so we have to store the result first:

result <- f handle

and doing <- gets rid of the IO . So return puts it back.

This is one of the tricky little things that confused me when I first tried Haskell. You're misunderstanding the meaning of the <- construct in do-notation. result <- f handle doesn't mean "assign the value of f handle to result "; it means "bind result to a value 'extracted' from the monadic value of f handle " (where the 'extraction' happens in some way that's defined by the particular Monad instance that you're using, in this case the IO monad).

Ie, for some Monad typeclass m, the <- statement takes an expression of type ma in the right hand side and a variable of type a on the left hand side, and binds the variable to a value. Thus in your particular example, with result <- f handle , we have the types f result :: IO a , result :: a and return result :: IO a .

PS do-notation has also a special form of let (without the in keyword in this case!) that works as a pure counterpart to <- . So you could rewrite your example as:

withFile' :: FilePath -> IOMode -> (Handle -> IO a) -> IO a  
withFile' path mode f = do  
    handle <- openFile path mode   
    let result = f handle  
    hClose handle  
    result

In this case, because the let is a straightforward assignment, the type of result is IO a .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM