Lista.dobrar à esquerda em OCaml

escrevi uma função, que adiciona todos os elementos da lista:

let rec add = function []->0 | h::t->h+add(t);;

Agora eu quero escrever a mesma função, mas usando List.fold_left, mas eu tentei várias mudanças, mas ainda tenho um erro. Primeiro tentei isto:

let rec add = function []->0 | h::t-> add List.fold_left((fun h t-> h+t) h t);;

Mas tive um erro e reparei nessa lista.o fold_ Left devolve um valor int, pelo que a recursão é desnecessária. Então eu mudei para: [8]}

let add = function []->0 | h::t -> List.fold_left ( fun h t-> h+t h t);;

Mas continuo a ter um erro sobre o tipo errado : Error: This expression has type int -> 'a -> 'b but an expression was expected of type 'a Mas Eu ... não sei como consertar isso, alguém pode explicar como usar List.fold_left Neste exemplo?

 1
Author: Pascal Cuoq, 2013-01-16

3 answers

O Fold_left opera em listas, tal como a sua função, aplicando uma função e acumulando um resultado de uma forma particular. Ele cuida e abstrai a recursão para você. Ele lida com a estrutura da lista, para que você possa lidar com a forma de combinar os elementos da lista de uma forma particular. Então, você precisa descobrir a função de ordem superior que você deseja aplicar ao fold_left que opera na lista da mesma forma.

Por exemplo, aqui estão duas maneiras de obter o elemento máximo de uma lista,...
let rec max_list smallest lst = match lst with 
    | []   -> smallest
    | h::t -> max_list (max smallest h) t

let max_list smallest lst =
    List.fold_left (fun acc x -> max acc x) smallest lst

Você vai notar a semelhança em alguns aspectos das funções; o caso base (menor) e como combinar elementos (usando a função max). Devias ver as mesmas semelhanças na tua função.

Olhando para trás para a sua implementação final,

let add = function | []->0
                   | h::t -> List.fold_left (fun h t-> h+t h t)

O problema aqui é que você tem um parêntesis deslocado...

let add = function | []->0
                   | h::t -> List.fold_left (fun h t-> h+t) h t

Mas isto pode ser simplificado, semelhante ao meu exemplo acima.

 11
Author: nlucaroni, 2013-01-16 22:04:49

Uma maneira de adicionar uma lista de inteiros:

# List.fold_left (+) 0 [1; 3; 5; 7];;
- : int = 16
 5
Author: to_the_crux, 2013-01-26 09:36:56

Se Núcleo.É utilizada uma DST, são necessários parâmetros nomeados, por exemplo,

List.fold_left ~f:(+) ~init:0 [1; 3; 5; 7];;
- : int = 16
 3
Author: Jim Fred, 2014-02-09 20:00:37