Search code examples
haskellmonadslazy-evaluationevaluationoperator-precedence

Evaluation of "something <- stuff" statements


Is it true that statements like something <- stuff are always evaluated in Haskell, even when something is not called in the rest of the code ? (is something <- stuff called an "action" ? - I don't know the technical wording).

If this is true, I have another question.

I have some code starting like this:

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

That is, if the argument voxmax is not Nothing, then voxelmax is not necessary, since max' = fromJust voxmax in this case. Therefore, if the answer to my first question is "Yes", how could I avoid the evaluation of voxelmax when it is not necessary ?


Solution

  • No, monadic binding is no guarantee that anything gets evaluated. There are lazy monads; e.g. the reader monad would not force the result of somefunction voxel unless voxmax was Nothing.

    But there's no reason to rely on such behaviors; it is easy to reliably avoid extra computation:

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

    You could consider using maybe, which is often shorter than an explicit case, as in:

        max' <- maybe (somefunction voxel) return voxmax