在计算表达式中构造 if.then 的 else 分支调用 Zero 背后的直觉



计算表达式中Zero方法的 msdn 文档指出

为计算表达式中if...then表达式的空else分支调用。

假设我们使用的是未定义Zeroidentity计算生成器。

let IdentityBuilder() = 
    member this.Bind(i, f) = f i
    member this.Return(i) = i
let identity = new IdentityBuilder()

允许使用以下代码

identity {
    printf "Hello World"
    return 1
}

但是,不允许使用以下代码,并且由于编译器错误而失败

仅当计算表达式生成器定义"Zero"方法时,才能使用此控件构造

identity {
    if true then printf "Hello World"
    return 1
}

为什么编译器坚持为else分支调用Zero?这背后的直觉是什么?

是否需要

Zero的实现取决于如何将if语句转换为来自monadic语法的函数调用。如果if的两个分支在语法上都是计算表达式,则翻译不涉及Zero。在这种情况下其中一个分支在语法上不是计算表达式或缺少转换后的表达式涉及Zero

我会通过这些案例。

ifelse 都是语法计算表达式

identity {
    if true then return 1 else return 2
    return 1
}

翻译为:

identity.Combine(
    if true then identity.Return(1) else identity.Return(2), 
    identity.Return(1)
)

缺少分支

identity {
    if true then return 1
    return 1
}

翻译为:

identity.Combine(
    if true then identity.Return(1) else identity.Zero(), 
    identity.Return(1)
)

这两个分支都已指定,但它们不是语法计算表达式

identity {
    if true then printf "Hello World" else ()
    return 1
}

翻译为:

identity.Combine(
    if true then printf "Hello World" else (); identity.Zero(), 
    identity.Return(1)
)

最后一种情况有点有趣,因为即使 if 语句返回有效的 monadic 值,使用 Zero 的翻译仍然会发生转换。最后一种情况也适用于没有elseif,当then部分在语法上不是计算表达式时。

编辑:我最近做了更多的研究,发现我原来的答案是不正确的。

相关内容

  • 没有找到相关文章

最新更新