Удваивающие элементы списка в f # - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь удвоить элементы данного списка, но получаю ошибку " Ожидалось, что это выражение будет иметь тип '' список '
но тут есть тип 'INT' " при определении нового списка

let list1 = [5;10;15;20;25;30]
let rec doubleListElements list =
    match list with
    |[]-> 0
    |head::tail ->
        let doubledList = [head*2::doubleListElements tail]
        0
let printList = doubleListElements list1
printfn "%A" printList

Я очень новичок в f # и не до конца понимаю, как все работает, я более привык к объектно-ориентированному подходу

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Вы можете использовать различные типы структур данных, такие как последовательности:

namespace FSharpBasics

module DoubleList =

    let private list1 = [ 5; 10; 15; 20; 25; 30 ]

    (*operations*)
    let doubleList (list: List<int>) =
        Seq.init list.Length (fun index -> list.[index] * 2)
            |> Seq.toList

    [<EntryPoint>]
    let main argv =
        doubleList list1 
            |> printf "%A"
        System.Console.ReadKey() |> ignore
        0
0 голосов
/ 01 мая 2018

Функция в вашем вопросе будет работать с некоторыми изменениями:

let rec doubleListElements list =
  match list with
  | [] -> []
  | head::tail -> head*2::doubleListElements tail

Первая важная вещь, которую нужно иметь в виду, это «что я хочу дать и получить от этой функции». В вашем случае ваш ввод int list, а желаемый вывод int list. Это означает, что где бы ваша функция не возвращала значение, оно должно быть int list. Ваша функция имеет два места, где возвращается значение:

  | [] -> [] // return empty list
  | head::tail ->
      head*2::doubleListElements tail // return a list (but recurse)

В вашей исходной функции ваши возвращаемые значения всегда 0, что, конечно, не соответствует типу возврата int list.

|[]-> 0 // return value
|head::tail ->
    let doubledList = [head*2::doubleListElements tail]
    0   // return value

В этом выражении создается doubledList, но это значение по существу отбрасывается, поскольку оно не используется и не является возвращаемым значением . Возвращаемое значение является окончательным значением в выражении: 0. Я думаю, что это очень распространенная ошибка, когда люди изучают функциональные языки, которые основаны на выражениях и основаны на императивных основанных на выражениях языках.

В этом конкретном выражении имеет значение только конечное значение. В языке, основанном на выражениях, вы могли видоизменить некоторое состояние программы перед возвратом значения (что также вполне возможно в F #, но обычно избегают изменчивости).

let foo x =
  let y = x + x // the value of this expression is discarded: y is unused
  x * x         // the value of this expression is returned

Единственное другое необходимое изменение - не переносить возвращаемый список в другой список в каждой рекурсии. head*2::doubleListElements tail это просто список. [head*2::doubleListElements tail] - это тот же список внутри другого списка , потому что он заключен в литералы списка в квадратных скобках. После этого изменения это работает:

val printList : int list = [10; 20; 30; 40; 50; 60]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...