Concat d'un résultat

Bonjour !!
Je débute en Ocaml et j’aurais besoin d’aide, voila je vous expliques.
J’ai fais une fonction dont le résultat est " 'a list -> 'a list * 'a list * 'a list " et je n’arrive pas à trouver comment faire pour concaténer le résultat de cette fonction.

Exemple pour être plus clair :
Mon résultat est le suivant : [1;2;4] [5;5] [8;7;12]
et je voudrais concaténer ce résultat en une seule et même liste donc je voudrais que le résultat final soit : [1;2;4;5;5;8;7;12]

Pouvez-vous m’aider je ne sais vraiment pas comment faire.

Merci à tous :slight_smile:

Bonjour,

Tu peux utiliser List.concat : 'a list list -> a list, par example:

let l1, l2, l3 = ta_fonction ... in
List.concat [l1; l2; l3]

Cheers,
Nicolás

2 Likes

Hi! I don’t know French, but I put your question into DeepL.

You can use @ to concatinate lists.

so:

let a, b, c = my_function some_list in
a @ b @ c
1 Like
let a, b, c = my_function some_list in
a @ b @ c

Note that in general it is not a good idea to use @ with more than two lists as performing repeated applications of @ can be much less efficient than a single call to List.concat.

Cheers,
Nicolás

3 Likes

Bonjour, merci pour votre réponse, je n’est pas le droit d’utiliser “List.concat”, j’ai malgré tout essayé quand même mais voila le message d’erreur :

Je ne comprend pas le “some_list” …

(Ce français a été créé par une machine, donc…)

par some_list, je voulais juste dire n’importe quelle liste que vous utilisez comme valeur d’entrée.

En ce qui concerne le message d’erreur, vous devez déstructurer le tuple qui est produit par votre fonction et mettre les éléments dans une liste, comme dans l’exemple donné par nojb.

1 Like

I did a quick benchmark on this, and there was a difference, but I was actually surprised by how similar they were overall. In some cases, the operator even beat the function!

let () =
  let l = Array.make 1000 "foo" |> Array.to_list in
  bench ~times:100 (fun () -> l@l@l@l@l@l) |> printf "%f ms\n";
  bench ~times:100 (fun () -> List.concat [l;l;l;l;l;l]) |> printf "%f ms\n"

(my benchmark function finds the average execution speed over the given number of times)

When I have the number at 100, as here, the output was:

0.000123 ms          
0.000106 ms

It seems like some optimizations kicked in when repeating the benchmark a thousand times:

0.000043 ms          
0.000055 ms

In this case the operator seems to beat the function, surprisingly!

I guess one should always benchmark the specific usecase.

1 Like

List.concat is implemented as repeated @ so I don’t see how it could be better.

2 Likes

Indeed, I misremembered!

Cheers,
Nicolás

1 Like

Merci pour votre aide, je ne comprend pas comment j’applique cette fonction à ma fonction…Je suis désolée de ne pas comprendre mais je débute…


Cette fonction me parait assez simple mais je n’arrive pas à comprendre pourquoi j’ai une erreur…je l’écrit peut être mal

(plus de français généré par des machines…)

On dirait que vous essayez de passer la valeur l à la fonction, mais elle n’a pas encore été définie. Si c’est la fonction dont vous avez parlé dans le post original, alors définissez une liste et utilisez-la comme entrée pour la fonction.

1 Like

According to your message Profile - blondedu42 - OCaml , what you call your result appears clearly to be of type 'a list * 'a list * 'a list * 'a list.
Let’s call it res.

In the following expression, the type-checker tells you that l is an unbound value because it’s used without having been defined before.

let a, b, c = pivot_er l in 
a @ b @ c

Your previous computation returns something that we called res (just to handle it ; in your program you don’t need that).
As @nojb told you, it can be my_function some_list or anything else: bip_function 1 "abc" true. We don’t need to know that. We know that res is the result returned by one function applied to some arguments.

# let res =  [1;2;4], [5;5], [8;7;12]
(* the result you get from a previous function applied to some arguments *)

val res : int list * int list * int list = ([1; 2; 4], [5; 5], [8; 7; 12])  

All that you need to do is pattern-matching on res, which is a triple, to extract each of its member in variables on which you can then apply the append function:

# let x, y, z = res in
  x @ y @ z

- : int list = [1; 2; 4; 5; 5; 8; 7; 12]

And you’re done.
Is that clear?

1 Like

Oui merci c’est très clair j’ai enfin compris mais j’ai une erreur la voila:

As the type-checker says, the last expression is ill-typed.
The problem is that let x, y, z has type list * list * list while pivot_er has type 'a list * 'a list * 'a list.

Your expression should be smthg like:

let x, y, z = pivot_er [1; 2; 4; 5; 5; 8; 7; 12] in (* put your own nbrs *)
x @ y @ z

(* simulation, because  I don't know partitionne_pivot 
and I can't apply pivot_er *)
# let x, y, z = ( [1; 2; 4], [5; 5], [8; 7; 12] ) in
  x @ y @ z

- : int list = [1; 2; 4; 5; 5; 8; 7; 12]

EDIT: first expression fixed (I forgot let res = ... that has nothing to do there uncommented).

The returned val(ue) can be bound to the name of your choice, depending on what you want to do.
If you want to get the value returned bound to a name, say blondedu42_mega_result, you can do:

# let blondedu42_mega_result = 
let x, y, z = pivot_er [1; 2; 4; 5; 5; 8; 7; 12] in
  x @ y @ z
(* simulated for me with ( [1; 2; 4], [5; 5], [8; 7; 12] )
instead of pivot_er [1; 2; 4; 5; 5; 8; 7; 12]  *)

val blondedu42_mega_result : int list = [1; 2; 4; 5; 5; 8; 7; 12]

Ok?

I think that you may have a look at https://www2.lib.uchicago.edu/keith/ocaml-class/functions.html to understand what is function application.

It’s one of the 21 short sections of that introduction to OCaml: https://www2.lib.uchicago.edu/keith/ocaml-class/class-01.html

2 Likes

Le problème est que quand j’écrit ma fonction donc:
soit x, y, z = pivot_er… etc,
je ne dois pas mettre de nombre dans cette fonction la, il faut que celle-ci fonctionne par rapport au résultat de pivot_er.

Merci de votre aide.

Est-ce que tu veux que la fonction pivot_er retourne directement une liste au lieu d’un n-uplet de listes, ou traiter le résultat courant avec une autre fonction?

1 Like

Je veux que pivot_er retourne un n-uplet de listes et que une autre fonction fasse un concat du resultat de pivot_er

Alors, ça me semble simple. Avec l’aide de la fonction ci-dessous:

let rec concat3 (a,b,c) =
  match (a,b,c) with
  | (x::xs,_,_) -> x::concat3 (xs,b,c)
  | ([],x::xs,_) -> x::concat3 ([],xs,c)
  | ([],[],x::xs) -> x::concat3 ([],[],xs)
  | ([],[],[]) -> []

Et après:

concat3 (pivot_er liste);
1 Like