Haskell中something <- stuff语句的求值规则及代码疑问
Haskell中
something <- stuff的常见疑问解答 1. 即使后续不用something,stuff也会被求值吗?
没错!在Haskell的do块里,<-的作用是绑定一个Monadic动作(比如IO动作)的结果到变量上。不管你后续代码有没有用到绑定的something,右边的stuff这个动作一定会被执行。这是Monad语义决定的——比如IO动作带有副作用,Haskell必须保证这些动作按顺序执行,哪怕你不关心结果。举个简单例子:
main = do _ <- putStrLn "我会被打印出来!" return ()
哪怕用下划线忽略了结果,这个打印动作还是会执行。
2. 这个语句是不是被称为“action”?
准确来说,stuff本身是一个action(比如IO Action),而something <- stuff是do块里的一个绑定语句,用来提取这个action的结果并绑定到变量上。所以不能说整个语句是action,action指的是那个能产生结果、带有Monadic语义的计算过程(也就是<-右边的部分)。
3. 你的代码会产生冗余求值吗?
看你给出的代码:
computeContour3d voxel voxmax level = do voxelmax <- somefunction voxel let max' = fromMaybe voxelmax voxmax
这里确实会有冗余!因为somefunction voxel是一个Monadic动作,只要你在do块里写了voxelmax <- ...,不管后面max'会不会用到voxelmax(也就是当voxmax不为Nothing时),这个动作都会被执行。如果somefunction是比较耗时的操作,那这部分开销就浪费了。
优化方案
你可以把动作的执行放在条件分支里,只在需要的时候才执行:
computeContour3d voxel voxmax level = do max' <- case voxmax of Just m -> return m -- 直接返回已有值,不执行somefunction Nothing -> somefunction voxel -- 只有需要时才执行动作 -- 后续使用max'的逻辑
这样就避免了不必要的冗余求值,只有当voxmax是Nothing时,才会调用somefunction voxel。
内容的提问来源于stack exchange,提问作者Stéphane Laurent
相关产品推荐
相关产品推荐

