Преобразование C # код в F # (если утверждение)

StackOverflow https://stackoverflow.com/questions/3120478

  •  30-09-2019
  •  | 
  •  

Вопрос

Я хотел бы знать, как преобразовать этот код построчно от 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 # имеет как минимум 2 формы, о которых я знаю.

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

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

И, конечно, вы должны абсолютно прочитать статью Брайана по этому вопросу. Это очень подробно и проходит многие из более тонких точек на перевод между двумя языками

Другие советы

Есть несколько проблем с вашим литеральным переводом. Прежде всего, есть немедленная проблема, которая вызывает ошибку компилятора: поскольку другие отметили, пусть привязки неизменяются по умолчанию. Тем не менее, есть хотя бы одна большая проблема: System.Collections.Generic.List<T> сильно отличается от F # 't list. Отказ Тип BCL представляет собой сметный список, поддерживаемый массивом, который обеспечивает постоянное время случайного доступа к элементам; Тип F # является неизмеренным в одиночном списке, поэтому доступ к NT-элементу принимает o (n) время. Если вы настаиваете на трансляции выражения выражения выражения, вы можете найти этот блог пост Брайаном ценный.

Я настоятельно рекомендую вам следовать советам других и попытаться считать себя, чтобы мыслить в идиоматическом 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 Функция, которая эквивалентна.

Краткий ответ: = не (Musable) назначение в f #.

Вопрос: Вы действительно имеете в виду col?

Предложения: попробуйте написать это без назначений. В вашем распоряжении есть рекурсионные и встроенные функции :-)

Вы должны прочитать

Как этот код 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 с атрибуция
Не связан с StackOverflow
scroll top