Здесь довольно много распаковать.
Первый, ваша функция не возвращает то, что вы хотите вернуть. Посмотрите, что последняя строка там, та, которая говорит newList
? Это возвращаемое значение вашей функции. Последняя строка тела функции - это возвращаемое значение. Таким образом, вы возвращаете обратный список, а не последний элемент.
Второй, так как вы не возвращает результат List.head
вызова, вы игнорируя его. Не делайте ничего с этим результатом. Не обращая внимания. И компилятор F # пытается помочь вам здесь: если вы игнорируете значение, это означает, что вы делаете что-то неправильно, и F # будет жаловаться (выдавать предупреждение), если вы это сделаете.
Но есть одно исключение из этого правила: вы можете игнорировать значение типа unit
. Логика идет, если у вас есть значение типа unit
, вы должны получить его в результате создания побочного эффекта. Потому что, если не было побочного эффекта, и нет никакого результирующего значения (unit
означает «нет значения»), то в чем смысл?
Итак, компилятор думает так: если вы проигнорировали значение, то это значение должно быть типа unit
. А так как List.head newList
имеет тип unit
, то newList
должен быть типа unit list
. И поэтому list
должен быть типа unit list
. И поэтому ваша функция имеет тип unit list -> unit list
(то есть она принимает параметр unit list
в качестве параметра и возвращает результат unit list
).
И так как вы пытаетесь передать int list
в функцию, которая принимает unit list
, компилятор не выдержит это: Expecting a unit list but given a int list
.
И, наконец,, переходящий список, чтобы получить его последнее значение, настолько расточительно! Вы перераспределяете целую кучу памяти, которая вам действительно не нужна. Менее расточительный способ добиться этого - использование рекурсии. Подумайте об этом так: последний элемент одноэлементного списка состоит в том, что один элемент, а последний элемент более длинного списка - последний элемент его хвоста. Мы можем написать, что прямо в F #:
let rec last list =
match list with
| [x] -> x // The last element of one-element list is the one element
| _::tail -> last tail // The last element of a longer list is the last element of its tail
| _ -> failwith "Empty list" // Otherwise fail
Плюс, есть готовая функция List.last
, что вы можете просто использовать (если это не домашнее задание, и в этом случае следует отметить, что в этом вопросе).
let mainP1()=
let list= [ 1; 2; 3]
printfn "Ultimul element al listei %A este %A" list (List.last list)
Остерегайтесь, однако, что не может быть последний элемент в списке - если список пуст. В этом случае List.last
(а также List.head
) будет сбой с исключением, что, как правило, не очень хорошая идея.Если вам нужно обработать случай пустого списка, смотрите на List.tryLast
вместо:
let mainP1()=
let list= [1; 2; 3]
match List.tryLast list with
| Some x -> printfn "Ultimul element al listei %A este %A" list x
| None -> printfn "Lista %A este goală" list
Там есть встроенная функция для этого: 'List.last'. Это домашнее задание? –