【发布时间】:2021-07-05 02:17:50
【问题描述】:
我是 F# 的新手,并且玩了一点,我已经使用过 C#。最近让我有点困惑的一件事是在函数中返回值。我明白一切都是一个表达式(如here 所述)并且以下代码不会编译或执行:
let foo x =
if x = 0 then x + 2 //The compiler will complain here due to a missing else branch.
x - 2
相反,您必须这样写:
let foo x =
if x = 0 then x + 2
else x - 2
我明白为什么会这样,并且在循环时也会出现类似的问题。
但考虑一个函数,它等于 C# 中列表的“包含”函数:
public static bool Contains(int num, List<int> list) {
foreach (int i in list) {
if (i == num) return true;
}
return false;
}
如果你逐一翻译,编译器会告诉你缺少一个 else 分支,我不明白为什么:
let Contains (num : int) list =
for i in list do
if i = x then true //Won't compile due to a missing else branch!
false
相反,您可能会编写这样的递归函数:
let rec Contains (num : int) list =
match list with
| [] -> false
| head::tail -> head = num || (Contains num tail)
我对此很好,但在某些情况下,很难进行模式匹配。真的没有办法做到上面描述的吗?不能使用像 yield 这样的关键字(或类似 C# 中的“return”)吗?
【问题讨论】:
-
我不懂 F#,但我知道您不应该逐字翻译语言。拥抱功能风格!在这里尝试使用高阶函数。
-
我知道您不应该逐字翻译,这确实是个坏主意,但在某些情况下,使用类似于 C# 中的样式的东西会很有用。
-
你能举一个/一些例子吗?
-
C#循环中break或return的解决方法很简单。研究 List、Seq 和 Array 模块中的函数。首先,看看 tryFind。
-
模块功能确实很一般。那些特别的,例如List.max,可以使用更通用的实现。无论您的 C# 循环做什么,都可以使用这些函数来实现。 Spaghetti code de luxe 可能是一个例外,但在转换为 F# 之前将其清理干净。
标签: c# function f# return contains