繁体   English   中英

将C#代码转换为F#(if语句)

[英]Converting C# code to F# (if statement)

我想知道如何将这个代码逐行从C#转换为F#。 我不打算使用任何一种F#的习语或类似的东西。 我试图了解如何将C#的构造直接映射到F#。

这是C#代码:

//requires l.Length > 0
int GetMinimumValue(List<int> l) {
    int minVal = l[0];

    for (int i = 0; i < l.Length; ++i) {
        if (l[i] > minValue) {
            minVal = l[i];
        }
    }

    return minVal;
}

这是我的F#尝试:

let getMinValue (l : int list) =
    let minVal = l.Head

    for i = 0 to (l.Length-1) do
        if (l.Item(i) > minVal) then
            minVal = col.Item(i)

    minVal

现在,这不起作用。 问题似乎与minVal = col.Item(i)行有关:

This expression was expected to have type     unit     but here has type     bool

有什么问题,真的吗?

如果要逐行转换,请尝试以下操作

let getMinValue (l:System.Collections.Generic.List<int>) =
  let mutable min = l.Item(0)
  for i = 0 to (l.Count-1) do
    if l.Item(i) < min then min <- l.Item(i)
  min

现在,为什么你得到那个特定的错误。 看看以下行

minVal = col.Item(i)

在F#中,这不是一个任务,而是一个比较。 所以这是一个产生bool值的表达式,但在for循环中所有表达式都必须为void / unit返回。 因此,您收到错误。

F#中的分配至少有两种我知道的形式。

// Assigning to a mutable value
let mutable v1 = 42
v1 <- 13

// Assigning to a ref cell
let v1 = ref 0
v1 := 42

当然,你应该完全阅读Brian关于这个主题的文章。 它非常详细,并且在两种语言之间进行翻译时有很多细节

您的直译有一些问题。 首先,存在导致编译器错误的直接问题:正如其他人所指出的那样,默认情况下让绑定是不可变的。 但是,至少还有一个大问题: System.Collections.Generic.List<T>与F#的't list非常不同。 BCL类型是一个由数组支持的可变列表,它提供对元素的恒定时间随机访问; F#类型是一个不可变的单链表,因此访问第n个元素需要O(n)时间。 如果你坚持做逐个表达式的翻译,你可能会发现Brian的博客文章很有价值。

我强烈建议你遵循别人的建议,尽量让自己适应惯用的F#,而不是直接翻译C#。 以下是在F#中编写一些相关函数的一些方法:

// Given an F# list, find the minimum element:
let rec getMinList l =
| [] -> failwith "Can't take the minimum of an empty list"
| [x] -> x
| x::xs ->
    let minRest = getMin xs
    min x minRest

请注意,这适用于任何元素类型的列表(需要注意的是元素类型需要comparable F#的角度相比,否则函数的应用程序将导致编译时错误)。 如果你想要一个适用于任何类型的序列而不仅仅是列表的版本,你可以将它基于Seq.reduce函数,该函数将作为其第一个参数提供的函数应用于序列中的每对元素,直到单个价值仍然存在

let getMin s = Seq.reduce min s

或者最重要的是,您可以使用内置的Seq.min函数,它是等效的。

简答: =不是(可变)F#中的赋值。

问题:你真的是指col吗?

建议:尝试用NO分配来写这个。 您可以使用递归和内置函数:-)

你应该读

这个C#代码在F#中是什么样的? (第一部分:表达和陈述)

我很失望没有其他答案已经将它联系起来,因为人们会问'如何将C#转换为F#'这个问题很多,而且我已经发布了很多这个答案链接,到现在为止一些其他的回答者应该知道这个:)

这是最直接的翻译:

let getMinimumValue (l: List<int>) =
  let mutable minVal = l.[0]

  for i=0 to l.Length-1 do
    if l.[i] > minVal then
      minVal <- l.[i]

  minVal

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM