2014-11-10 3 views
0

Привет, я решил проблему с задачей elalier. Теперь, если у меня есть список list = [2; 3; 2; 6] хотят перевести его так [2; 5; 7; 13].f # список сумм по-другому

Я объявил x как мой первый элемент и xs как мой отдых и использовал List.scan. Идея ниже

(fun x n -> x + n) 0  
but this make something like this  
    val it : int list = [0; 2; 5; 7; 13] 

Как переписать его, чтобы сделать список глядя, как это [2; 5; 7; 13] с использованием любого исходного параметра. Когда я удаляю 0, я получаю сообщение об ошибке.

Другой вопрос, как это будет выглядеть, как List.Fold я пытался написать что-то подобное, но он может получить только сумму этого списка;. (

+0

Просто возьмите хвост выходного списка: 'list |> List.scan (+) 0 |> List.tail' – Lee

+0

Спасибо;) Мне это было нужно :) Любые намеки, как сделать то же самое со складкой? –

ответ

0

Вот как я хотел бы сделать это со складкой (с примечаниями типа):

let orig = [2; 3; 2; 6] 

let workingSum (origList:int list) : int list = 
    let foldFunc (listSoFar: int list) (item:int) : int list = 
     let nextValue = 
      match listSoFar with 
      | [] -> item 
      | head::_ -> head + item 
     nextValue::listSoFar 

    origList |> List.fold foldFunc [] |> List.rev 

За помощью обучения складка, вот как я хотел бы сделать это с помощью рекурсивной функции:

let workingSum' (origList: int list): int list = 
    let rec loop (listSoFar: int list) (origListRemaining:int list): int list = 
     match origListRemaining with 
     | [] -> listSoFar 
     | remainHead::remainTail -> 
      let nextValue = 
       match listSoFar with 
       | [] -> remainHead 
       | head::_ -> head + remainHead 
      loop (nextValue::listSoFar) remainTail 

    origList |> loop [] |> List.rev 

Обратите внимание, что подпись внутренней функции loop действительно похожа на foldFunc предыдущего примера с одним существенным отличием: вместо передачи в следующем элементе она передается в остальной части исходного списка, который не был все еще обработано. Я использую выражение соответствия для учета двух разных возможностей этого остатка в исходном списке: либо этот список пуст (это значит, что мы закончили), либо нет (и нам нужно вернуть рекурсивный вызов к следующему шаг).

+0

вы можете объяснить, как он работает? И почему я должен обновить список позже? Я хочу кое-что узнать: P –

+0

Конечно. Состояние, в котором строится свод, само по себе является списком. По мере того, как выполняется сгиб, foldFunc выполняется по каждому элементу поочередно. Функция fold имеет два шага: во-первых, определить значение, которое необходимо добавить в список состояний; второй минус, что элемент с прошедшим в списке состояний для продукта нового состояния. На самом деле это похоже на хвостовые рекурсивные вызовы. –

+0

Я добавил рекурсивную функцию, выполняющую то же самое. Вы можете следовать за ним? –

Смежные вопросы