Converting C# code to F# (if statement)

天大地大妈咪最大 提交于 2019-12-05 07:46:20

If you want to convert it line by line then try the following

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

Now as to why you're getting that particular error. Take a look at the following line

minVal = col.Item(i)

In F# this is not an assignment but a comparison. So this is an expression which produces a bool value but inside the for loop all expressions must be void/unit returning. Hence you receive an error.

Assignment in F# has at least 2 forms that I am aware of.

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

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

And of course, you should absolutely read Brian's article on this subject. It's very detailed and goes over many of the finer points on translating between the two languages

There are a few problems with your literal translation. First of all, there's the immediate problem which causes the compiler error: as others have noted, let bindings are immutable by default. However, there's at least one other big problem: System.Collections.Generic.List<T> is very different from F#'s 't list. The BCL type is a mutable list backed by an array, which provides constant time random access to elements; the F# type is an immutable singly linked list, so accessing the nth element takes O(n) time. If you insist on doing expression-by-expression translation, you may find this blog post by Brian valuable.

I'd strongly recommend that you follow others' advice and try to acclimate yourself to thinking in idiomatic F# rather than literally translating C#. Here are some ways to write some related functions in 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

Note that this works on lists of any element type (with the caveat that the element type needs to be comparable from F#'s perspective or the application of the function will cause a compile-time error). If you want a version which will work on any type of sequence instead of just on lists, you could base it on the Seq.reduce function, which applies the function supplied as its first argument to each pair of elements in a sequence until a single value remains.

let getMin s = Seq.reduce min s

Or best of all, you can use the built-in Seq.min function, which is equivalent.

Short answer: = is not (mutable) assignment in F#.

Question: Do you really mean col?

Suggestions: Try to write this with NO assignments. There is recursion and built-in functions at your disposal :-)

You should read

What does this C# code look like in F#? (part one: expressions and statements)

I am disappointed that none of the other answers already linked it, because people ask the 'how to convert C# to F#' question a lot, and I have posted this answer link a lot, and by now some of the other answerers should know this :)

This is the most literal translation possible:

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
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!