caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Diego Olivier Fernandez Pons" <FernandezPons@iFrance.com>
To: <Vincent.Barichard@info.univ-angers.fr>
Cc: "Caml" <caml-list@inria.fr>
Subject: Re: [Caml-list] Function call with a list of parameters
Date: Wed, 12 Dec 2001 23:31:53 +0100	[thread overview]
Message-ID: <00a201c18360$f8135480$074cf2c3@Utilisateur> (raw)
In-Reply-To: <15383.12155.733583.353752@helios.info-ua>

Vincent Barichard a écrit

let fourAdd x y z w = x + y + z + w;;
myFunctionCall fourAdd [1 ; 2 ; 3 ; 4];;
#   - : int = 10

On a effectivement un problème de typage de la fonction donnée en
argument (puisque le type "fonction" sans précision d'arité n'existe
pas en Caml). Si le code suivant marche, on est immédiatement en
difficultés quand on veut changer le nombre d'arguments (même dans un
cas fini).

let applique f = function
  | [x; y; z; t] -> f x y z t
  | _ -> failwith "type error"
;;

applique addfour [1; 2; 3; 4];;
#   - : int = 10

let applique f = function
  | [x; y; z] -> f x y z
  | [x; y; z; t] -> f x y z t
  | _ -> failwith "type error"
;;

# This expression has type 'a but is here used with type 'b -> 'a

Une première idée serait de passer par un type somme

type fonction =
  | Unaire of (int -> int)
  | Binaire of (int -> int -> int)
  | Ternaire of (int -> int -> int -> int)
;;

puis faire un filtrage dans lors le l'application

let appliquer f liste =
  match f with
  | Unaire g -> let [x] = liste in g x
  | Binaire g -> let [x; y] = liste in g x y
;;

Outre les avertissements que génère le code et la complication que
requiert le passage au type somme proposé, ce code a le grand
désavantage d'imposer que l'arité de f soit bornée.

Peut on contourner la difficulté ? On remarquera que l'on peut écrire
différemment le cas particulier que vous avez proposé :

let add x total = x + total;;
let addFour x y z t = add x (add y (add z (add t 0)));

Et appliquer la fonction add sur une liste de longueur quelconque est
tout à fait possible.

Peut-on éviter d'appliquer à chaque étape la même fonction ? oui !

let add2 x total = total + x + 2;;
let add3 x total = total + x + 3;;
let add5 x total = total + x + 5;;
let add7 x total = total + x + 7;;

let add17 x y z t = add2 x (add3 y (add5 z (add7 t 0)));;

Si l'on dispose d'une liste de fonctions, on peut sans difficulté
l'appliquer au moyen de :

let rec applique_fonctions argument = function
  | [] -> argument
  | (tete :: queue) -> applique_fonctions (tete argument) queue
;;

# val applique_fonctions : 'a -> ('a -> 'a) list -> 'a = <fun>

Autrement dit, si vous arrivez à transformer votre fonction à n
arguments en composée de n fonctions d'arité fixe, vous pourrez alors
 les appliquer à une liste de n paramètres indépendamment de n.
Cela dit, ce dernier problème n'est ni plus aisé, ni toujours soluble.

        Diego Olivier

-------------------
Bug reports: http://caml.inria.fr/bin/caml-bugs  FAQ: http://caml.inria.fr/FAQ/
To unsubscribe, mail caml-list-request@inria.fr  Archives: http://caml.inria.fr


  reply	other threads:[~2001-12-12 23:03 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-11 16:31 Vincent Barichard <Vincent Barichard
2001-12-11 22:59 ` Chris Hecker
2001-12-11 23:26   ` Bruce Hoult
2001-12-12  9:35   ` Markus Mottl
2001-12-12 10:20   ` Vincent Barichard <Vincent Barichard
2001-12-12 22:31     ` Diego Olivier Fernandez Pons [this message]
2001-12-13  0:20       ` Bruno Pagano
2001-12-13  0:17         ` Diego Olivier Fernandez Pons
2001-12-14 13:26           ` Alain Frisch
2001-12-17  7:40             ` Francois Pottier
2001-12-12 13:52   ` Francois Pottier
2001-12-12 18:54     ` Chris Hecker
2001-12-12 19:04       ` Patrick M Doane
2001-12-12 23:49       ` Bruce Hoult
2001-12-13  7:41       ` Francois Pottier
2001-12-12  9:31 ` Jim Farrand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='00a201c18360$f8135480$074cf2c3@Utilisateur' \
    --to=fernandezpons@ifrance.com \
    --cc=Vincent.Barichard@info.univ-angers.fr \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).