繁体   English   中英

如何在haskell中实现withFile

[英]How withFile is implemented in haskell

haskell教程之后 ,作者提供了withFile方法的以下实现:

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

但为什么我们需要将result包装return 提供的函数f是否已经返回IO因为它的类型Handle -> IO a

你是对的: f已经返回一个IO ,所以如果函数是这样编写的:

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

没有必要返回。 问题是hClose handle介于两者之间,所以我们必须先存储结果:

result <- f handle

并做<-摆脱IO 所以return把它放回去。

当我第一次尝试Haskell时,这是让我困惑的棘手小事之一。 你误解了<-构造在do-notation中的含义。 result <- f handle并不意味着“将f handle的值赋给result ”; 它意味着“将result绑定到从f handle的monadic值中提取的值”(其中'extract'以某种方式发生,由您正在使用的特定Monad实例定义,在本例中为IO monad)。

即,对于一些Monad类型类m, <-语句在右侧采用类型为ma的表达式,在左侧采用类型a的变量,并将该变量绑定到一个值。 因此,在您的特定示例中,使用result <- f handle ,我们有类型f result :: IO aresult :: areturn result :: IO a

PS do-notation还有一种特殊形式的let (在这种情况下没有in关键字!),它作为<-的纯粹对应物。 所以你可以将你的例子重写为:

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

在这种情况下,因为let是一个简单的赋值, result的类型是IO a

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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