【问题标题】:Evaluation of "something <- stuff" statements评估“某事<-东西”陈述
【发布时间】:2018-04-12 08:56:42
【问题描述】:

something &lt;- stuff 这样的语句是否总是在Haskell 中进行评估,即使在其余代码中没有调用something ? (something &lt;- stuff 被称为“动作”吗?-我不知道技术措辞)。

如果这是真的,我还有一个问题。

我有一些这样开头的代码:

computeContour3d voxel voxmax level = do
    voxelmax <- somefunction voxel
    let max' = fromMaybe voxelmax voxmax

也就是说,如果参数voxmax 不是Nothing,那么voxelmax 是不必要的,因为在这种情况下max' = fromJust voxmax。因此,如果我的第一个问题的答案是“是”,我该如何避免在没有必要的情况下评估voxelmax

【问题讨论】:

  • 不是本身,这取决于使用的单子。事实上,例如,对于 Maybe monad,很可能会评估大量数据。对于 I/O monad,可以保证 I/O actions 按照您指定的顺序完成。
  • @WillemVanOnsem somefunction voxel 返回一个IO (something)
  • 那么可以保证 I/O 操作按照您定义的顺序完成。但这本身并不意味着围绕这些 I/O 操作(在 Haskell 级别)发生的所有计算都已完成。
  • 具体如果你在IO,如果你想懒惰地执行一个动作,你可以使用unsafeInterleaveIO。不过这并不常见——将所有重要的东西从IO 中推送到纯代码中被认为是更好的设计,这总是尽可能的懒惰。

标签: haskell monads lazy-evaluation evaluation operator-precedence


【解决方案1】:

不,一元绑定不能保证任何东西都会被评估。有惰性单子;例如读者 monad 不会强制 somefunction voxel 的结果,除非 voxmaxNothing

但是没有理由依赖这种行为;很容易可靠地避免额外的计算:

computeContour3d voxel voxmax level = do
    max' <- case voxmax of
        Nothing -> somefunction voxel
        Just max -> return max
    -- use max'

您可以考虑使用maybe,它通常比显式的case 短,例如:

    max' <- maybe (somefunction voxel) return voxmax

【讨论】:

  • 嗯,好的。 somefunction 返回一个IO,在另一种情况下我不认为将&lt;-return 一起使用。谢谢!
【解决方案2】:

是不是真的像 something

一般来说,不。 IO monad 强制进行此类评估,但许多其他人不这样做。

something &lt;- stuff 被称为“动作”吗?

通常该行将被称为一元绑定。一些单子(例如列表)并没有真正以任何有意义的方式“行动”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-20
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多