문제

I'd like to know how to convert this code line by line from C# to F#. I am not looking to use any kind of F#'s idioms or something of the like. I am trying to understand how to map directly C#'s constructs to F#.

Here is the C# code:

//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;
}

And here is my F# attempt:

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

Now, this ain't working. The problem seems to be related with the minVal = col.Item(i) line:

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

What is the problem, really?

도움이 되었습니까?

해결책

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top