F# 计算表达式中的Run方法

F# 计算表达式中的Run方法,f#,F#,计算方法中的Run()方法的状态是什么?我在几个例子(,)中看到过它,我在其中看到了F#的编译器源代码,但它不在或中。我就此提交了一份报告,报告以“故意”的方式关闭,没有进一步解释 那么它是否已被弃用/未记录/不受支持?我应该避免吗 更新:MS Connect问题状态立即更改,MSDN页面更新为包含Run()6.3.10计算表达式 更具体地说,是计算 表达的形式是 生成器expr{cexpr},其中cexpr, 从句法上讲,语法 带附加字符的表达式 在comp expr中定义的构造。 计算表达式

计算方法中的
Run()
方法的状态是什么?我在几个例子(,)中看到过它,我在其中看到了F#的编译器源代码,但它不在或中。我就此提交了一份报告,报告以“故意”的方式关闭,没有进一步解释

那么它是否已被弃用/未记录/不受支持?我应该避免吗


更新:MS Connect问题状态立即更改,MSDN页面更新为包含Run()

6.3.10计算表达式

更具体地说,是计算 表达的形式是 生成器expr{cexpr},其中cexpr, 从句法上讲,语法 带附加字符的表达式 在comp expr中定义的构造。 计算表达式用于 序列和其他非标准 F#表达式的解释 语法。表达式生成器expr{ cexpr}转换为

对于新变量b。如果推断的b类型上不存在方法运行,则 表达式,则省略该调用。同样,如果在检查此表达式时,>类型的b上不存在方法延迟,则忽略该调用


我认为
Run
方法是在开发过程的后期添加的,所以这可能是文档中缺少它的原因之一。正如desco所解释的,该方法用于“运行”计算表达式。这意味着无论何时编写
expr{…}
,翻译后的代码都将被包装在对
Run
的调用中

这个方法有点问题,因为它破坏了组合性。例如,对于任何计算表达式,要求以下两个示例代表相同的内容是明智的:

expr { let! a = foo()           expr { let! c = expr {  
       let! b = bar(a)                   let! a = foo()
       let! c = woo(b)                   let! b = bar(a) 
       return! zoo(c) }                  return! woo(b) }
                                       return! zoo(c) }
但是,
Run
方法将仅在左侧示例中的整体结果上调用,在右侧调用两次(对于整体计算表达式和嵌套表达式)。该方法的一个常见类型签名是
M->T
,这意味着甚至不会编译正确的代码

因此,在创建monad时避免使用它是一个好主意(因为它们通常是在Haskell中定义和使用的),因为
Run
方法破坏了monad的一些好的方面。然而,如果你知道你在做什么,那么它会很有用


例如,在my
break
代码中,计算生成器立即执行其主体(在声明中),因此添加
Run
以展开结果不会破坏合成性-合成意味着只运行另一个代码。然而,为
async
和其他延迟计算定义
Run
根本不是一个好主意。。。我实际上是用它来实现组合性(代码:)@Mauricio:我不完全理解你的代码,但一个重要的区别是你的
运行
有一个类型
m->m
——破坏兼容性的情况通常有类似
m->t
(例如,当ComputationBuilder创建并启动任务时).就我的博客而言,我是F#的新手。我对Run()等高级概念的使用不一定代表最佳实践。当我刚刚学习语言结构时,我倾向于探索其奇怪和非典型的用法,哈哈。
expr { let! a = foo()           expr { let! c = expr {  
       let! b = bar(a)                   let! a = foo()
       let! c = woo(b)                   let! b = bar(a) 
       return! zoo(c) }                  return! woo(b) }
                                       return! zoo(c) }