为什么这个 F# 计算表达式会发出警告?
此代码:
type Result = Success of string
type Tracer() =
member x.Bind(p: Result, rest: (string -> Result)) =
match p with
| Success s -> rest s
let tracer = new Tracer()
let t = tracer {
let! x = Success "yes!"
let! y = Success "waste of time"
return! Success x
}
printfn "%A" t
打印 Success "yes!"
但给出警告,暗示它不应该工作:
File1.fs(19,3): warning FS0708: This control Construction may only be如果计算表达式构建器定义了“ReturnFrom”方法,则使用
似乎是一个奇怪的警告:如果它是正确的,那么代码不应该工作。难道真的只是说构建器必须合成 ReturnFrom 吗?
(F# 版本 1.9.7.4,针对 .NET Framework 版本 v4.0.21006 进行编译)
This code:
type Result = Success of string
type Tracer() =
member x.Bind(p: Result, rest: (string -> Result)) =
match p with
| Success s -> rest s
let tracer = new Tracer()
let t = tracer {
let! x = Success "yes!"
let! y = Success "waste of time"
return! Success x
}
printfn "%A" t
prints Success "yes!"
But gives a warning that implies that it shouldn't work:
File1.fs(19,3): warning FS0708: This control construct may only be used if the computation expression builder defines a 'ReturnFrom' method
Seems like a strange warning: if it's right, then the code shouldn't work. Is it really just saying that the builder had to synthesize ReturnFrom?
(F# Version 1.9.7.4, compiling for .NET Framework Version v4.0.21006)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已将问题发送至[电子邮件受保护],这是一个错误。他们说这将是下一个版本中的错误。
(他们几乎立即回复,在感恩节也不例外 - 我只是花了一段时间才将信息放在这里。)
I sent the question to [email protected], and it's a bug. They said it'll be an error in the next release.
(They responded almost immediately, on Thanksgiving no less - it just took me a while to put the info here.)
我很惊讶这有效。 规范第 6.10 节 在未指定时没有提及任何有关合成
ReturnFrom
的内容。是否有理由不将member x.ReturnFrom v = v
放在构建器上?或者一个member x.Return(v) = Success v
,这样你就可以用return x
结束你的tracer
块,这会更有效传统的?I'm surprised that this works. Section 6.10 of the spec doesn't mention anything about synthesizing
ReturnFrom
when it's not specified. Is there a reason not to just put amember x.ReturnFrom v = v
on the builder? Or amember x.Return(v) = Success v
, so that you could end yourtracer
block withreturn x
, which would be more traditional?