F#:函数中返回点较多,如何处理?
在复杂函数中返回值时遇到问题。例子总是更好:
考虑下面的函数:
let myf (mypar: int) =
mypar + 1
这里没有探针,这个函数编译正确,签名是:
val myf: int -> int
好的,好吧。现在考虑这段代码:
let myf (mypar: int) =
if mypar = 2 then
4 (* ERROR *)
mypar + 1
这不起作用:
这个表达式应该有类型unit,但这里有int
每当我尝试从函数返回时,当我在if
,一个< code>while 一个 for
或每个其他块。我认为问题在于确保所有可能的返回路径返回相同的类型,但这里我不明白会发生什么。
请注意,如果我插入一个 ()
单元,则一切正常:
let myf (mypar: int) =
if mypar = 2 then
() (* No error *)
mypar + 1
但是该单元不会使我的函数返回!它继续! 此外,你能解释一下 F# 如何处理这个问题吗???
谢谢
I have a problem when returning values in complex functions. Examples are always better:
Consider the following function:
let myf (mypar: int) =
mypar + 1
Well no probel here, this function is compiled correctly and the signature is:
val myf: int -> int
OK, well. Now consider this code:
let myf (mypar: int) =
if mypar = 2 then
4 (* ERROR *)
mypar + 1
This does not work:
This expression was expected to have type unit but here has int
This error is raised everytime I try to return from my function when I am inside a if
, a while
a for
or every other block. I thought that the problem was assuring that all possible return paths return the same type, but here I do not understand what happens.
Please note that if I insert a ()
unit everything works for example:
let myf (mypar: int) =
if mypar = 2 then
() (* No error *)
mypar + 1
But that unit does not make my function return!!! it continues!!!
Furthermore, could you please explain me how F# handles this???
Thankyou
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
要添加更多细节,您的方法的问题在于 F# 中的所有内容都是表达式。这使得推理程序变得更加容易(因为您不需要跟踪当前正在执行的语句),但这意味着您始终必须编写完整的表达式。
如果您尝试编写类似
return
的内容,就好像您在 C# 中编写了以下内容(这可能解释了为什么 F# 不允许此类操作):为什么您没有收到错误当你写
if .. then ()
时?()
表达式创建一个特殊的unit
类型值,因为它只有一个有效值。 F# 允许您在返回unit
时编写if .. then
而无需使用else
,因为它可以计算出else
> 分支必须返回唯一现有的单位值,因此它将您的代码视为:唯一的区别是抛出异常(使用
raise
),其行为与 C# 中一样。您可以使用异常来中断函数,但最好重写代码以获得完整的有效表达式。To add some more details, the problem with your approach is that everything in F# is an expression. This makes it a lot easier to reason about your programs (because you don't need to keep track of the currently executing statement), but it means that you always have to write a complete expression.
If you try to write something like
return
, it would be as if you wrote the following in C# (This probably explains why F# doesn't allow this kind of things):Why didn't you get error when you wrote
if .. then ()
? The()
expression creates a value of typeunit
that is special, because it has only one valid value. F# allows you to writeif .. then
withoutelse
when returningunit
, because it can figure out that theelse
branch has to return the only existing unit value, so it sees your code as:The only difference is throwing an exception (using
raise
) which behaves just like in C#. You could break out of a function using exception, but it is much better idea to rewrite the code to have a complete valid expression.