prog fonctionnelle (fct d'ordre sup, ocaml) - Divers - Programmation
Marsh Posté le 16-12-2005 à 21:41:29
Là tu déclares h comme une fonction prenant deux paramètres f et y (function f -> function y), et qui renvoie comme résultat y plus le résultat de f appliqué à y.
Comme ça utilise + tu en déduis que y est un entier, donc que la fonction f passé en paramètre à h prends un entier en paramètre (en l'occurence y), et que par conséquent elle renvoie un entier (puisqu'on additionne le résultat à y).
Code :
|
y'a de nombreuses façon d'écrire une fonction en caml, là t'en vois 4 mais elles sont équivalentes, ça dépend de comment tu préfère les écrire, la troisième est sûrement plus claire quand on débute.
Pour la définition exacte de fonction d'ordre supérieur, je ne m'en souviens plus, mais ça permet de généraliser sur des fonctions, par exemple en renvoyant comme résultat une fonction (qui peut-être utilisée par la suite (passé en paramètre à une autre fonction par exemple)), ou en prenant une fonction en paramètre, ce qui est le cas ici avec ta fonction h qui prends une fonction f en premier paramètre. Du coup on peut appeler ça une fonction d'ordre supérieure.
Par exemple un exemple du style:
Code :
|
Marsh Posté le 16-12-2005 à 23:15:24
merci pour votre réponse, j'ai compris c'est en gros f(g(y))
par contre je ne comprends pas les formes du genre let h f y = (f y y y) ca represente quoi mathématiquement ?
encore merci pour votre aide...
Marsh Posté le 16-12-2005 à 23:36:39
Pour let h f y = (f y y y);;
C'est tout simplement la fonction h qui prend en paramètre une fonction f et une variable y comme tout à l'heure.
La seule différence c'est que cette fois ci f prends 3 paramètres au lieu d'un seul comme dans l'exemple du dessus.
par exemple :
Code :
|
Marsh Posté le 22-12-2005 à 22:45:01
Bonjour,
que signifie par exemple
val xx : ('a -> 'b -> 'c) -> 'a -> 'b -> 'c = <fun>
ou
val xx : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
je ne comprends pas les parenthèses. Je sais que 'a et 'b designe des types généraux mais je ne comprends pas les types calculés
merci pour votre aide
Marsh Posté le 22-12-2005 à 23:22:30
Alors pour le premier, xx est une fonction qui prends 3 paramètres, le premier est une fonction qui prends deux paramètres, et les deux autres arguments sont les paramètres de la fonction passé en premier à xx .
Les parenthèses pour le premier argument de xx sont là pour bien préciser que c'est une fonction qui est attendue.
Par exemple :
Code :
|
Pour le deuxième : val xx : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b = <fun>
xx est donc une fonction qui prends 3 arguments, les deux premiers sont des fonctions (parenthésage).
Voilà ce qu'on peut voir du résultat de l'évaluation de la fonction, xx prends en deuxième paramètre une fonction qui prend du type 'c, et renvoie du type 'a, et le premier paramètre est une fonction qui prend du type 'a (le type de retour de la deuxième fonction) et qui renvoie du type b (c'est le type attendue en résultat de la fonction xx). Et la nourriture pour le deuxième paramètre de xx c'est son 3ème paramètre (type 'c qu'on donne à bouffer au deuxième paramètre qui prends du type 'c).
On peut donc avoir ça :
Code : |
Si t'as d'autres questions ou si tu veux une autre explication, suffit de demander .
Marsh Posté le 23-12-2005 à 11:34:25
Rebonjour,
une dernière chose : pourriez vous m'expliquer la curryfication ?
je comprends la curryfication sur deux parametres mais quand yen a plus..
en gros cest au lieu de dire let fonction (x,y) =x*y;; par exemple, ont dit que cest à peu pres equivalent à fonction x->(fonction y->x*y);; ou qui s´ecrit simplifié fonction x y = x*y ;;
ca ça va, mais quand ya plus de parametres... genre
let fonction f g h i j k= f g h i j k;; ou que je mets des parenthèses aléatoirements comme let fonction f g h i j k= f (g h) i (j k);; je ne vois plus comment c'est sous forme cartesienne ou le lien
Marsh Posté le 23-12-2005 à 12:54:41
Bon pour la curryfication si je me souviens bien y'a deux définitions, la première c'est pour quand tu passe les paramètres sous forme d'un n-uplet, la deuxième c'est quand le résultat est une fonction.
Donc au lieu d'avoir
Code :
|
C'est à toi de choisir celle qui te plaît le plus, personnellement je préfère la première, mais c'est un choix à faire, dans certains cas ça peut-être plus avantageux de passer un n-uplet plutôt que n paramètres.
pour ta fonction :
Code :
|
ça dit que fonction renvoie le même résultat que la fonction f, et que la fonction f prends 5 arguments qui sont g, h, i, j, et k.
Alors que pour :
Code :
|
ça dit que fonction renvoie le même résultat que la fonction f, mais que la fonction f prends 3 arguments, et que g et j sont des fonctions à un argument, si dans ce cas tu enlève le parenthésage, alors l'interpréteur caml ne pourra pas savoir quels sont les 3 paramètres de f, il pourrait prendre g h et i, mais ils n'auraient pas les bon types, et il resterait j et k dont il ne saurais pas quoi faire.
Marsh Posté le 23-12-2005 à 19:16:04
Bonjour,
Je cherche à calculer la somme de k=0 à n de (x^(2*k)) /(2*k)! (il s'agit de la série cosinus hyperbolique).
dans la question il etait conseille de définir d'abord une fonction terme de profil float->int->float qui calcul le terme de la somme, j'ai réussi :
Code :
|
Mais je ne parviens pas à écrire la fonction récursive serie_cosh de profil float->int->float qui calcule la somme pour les valeurs de n et x passés en paramètre. Je pense qu'il faut utiliser le pattern matching, mais je ne vois pas trop comment faire.En fait je ne sais pas du tout "passer des valeurs en paramètres"
Merci d'avance pour votre aide..
Marsh Posté le 23-12-2005 à 22:32:50
Bonsoir ,
Alors je viens de te faire ça, en fait il te manque la fonction qui va itérer sur les k, pour renvoyer le resultat, alors voila comment je viens de te faire ça :
Je ne sais pas si tu as encore vu ce qu'est la recursivité terminale ou non, j'ai fait ça en recursif terminal, donc si tu comprends pas un truc n'hésite pas à demander.
Code :
|
On a une approximation pas trop mauvaise du coup .
Suffit de changer la precision, et logiquement ça devrait s'affiner.
Sinon tu peux toujours te refaire la fonction exponentielle, et puis l'utiliser pour trouver le cosinus hyperbolique .
Marsh Posté le 23-12-2005 à 22:40:43
Disons que je ne comprends pas trop pourquoi tu parviens à trouver mon_cosh x en fonction que d'un paramètre, car après j'avais une question calculer la valeur de serie_cosh 0.2 5, donc c'est serie_cosh x n en fonction de deux paramètres. il n'y avait riend 'autre, ils conseillent au debut la fonction terme puis apres la fonction serie_cosh en fonction de x et n passés en parametres. Je n'ai pas vu cette récurrence mais j'ai à peu pres compris ce que t'as fais quand même
Marsh Posté le 23-12-2005 à 22:48:52
Dans ton exemple serie_cosh 0.2 5;; le 5 c'est la precision que j'ai mis à 10
donc tu peux remplacer par ça :
Code :
|
Marsh Posté le 24-12-2005 à 17:37:06
Bonsoir, besoin d'une petite aide sur les listes:
j'ai un dictionnaire représenté par une liste de couple (mot français, mot anglais)
ex : let dico = [("un","one" ); ("chat","cat" )] ;;
comment écrire une fonction trad qui à un mot français donné associe le mot anglais correspondant
son profil devra etre (string*string) list -> string -> string.
ex : trad dico "un" renverra "one"
j'ai essayé mais bon ça ne marche pas
Code :
|
merci et bon reveillon
Marsh Posté le 24-12-2005 à 18:21:26
Ben il suffit juste de parcourir la liste dico et voir si le premier élément du couple élément de la liste correspond au mot recherché ou non.
Ça doit donner quelque chose comme ça :
Code :
|
Bon réveillon à toi aussi.
Marsh Posté le 25-12-2005 à 11:20:48
Bonjour, une toute derniere chose et j'arrete d'abuser de votre patience...
que font exactement
| (m, m')::_ when m = mot -> m'
| _::t -> trad t mot
?
je sais que les :: servent à ajouter un element dans une liste mais je n'ai pas bien saisi l'action qu'ils ont ici..
encore merci et joyeux noel
Marsh Posté le 25-12-2005 à 14:36:15
Ils décrivent un motif. Le motif "h::t" représente une liste dont la tête est "h" et la queue est "t". Sachant que "_" permet d'ignorer ce qu'est la tête.
Ainsi "(m, m')::_" représente une liste dont la tête est le couple "(m, m')" (ce qui est cohérent puisque tu as une liste de 2-uples).
Note que les motifs ne sont pas forcément exclusifs et sont évalués dans l'ordre. Ainsi les deux premier motifs filtrent la même chose (sauf cas particulier que j'aurais raté ), sauf qu'arrive au deuxième motif on a déjà "filtré" le cas où m = mot.
En fait on pourrait écrire :
|
Marsh Posté le 31-12-2005 à 18:55:48
bonjour, comment trier une liste de mots dans l'ordre alphabetique?
j'utilise les operateurs >, < et = sur les string mais j'arrive pas a ecrire une fonction correcte
merci pour votre aide
Marsh Posté le 31-12-2005 à 19:47:19
Dans le module String tu as "String.compare" donc tu peux faire :
List.sort String.compare ta_liste ;;
Marsh Posté le 31-12-2005 à 19:50:10
oki merci
mais sinon ya pas une fonction ? j'essaye des trucs depuis quelques heures mais sans succès
let rec range liste = match liste with
t::q -> if t>q then q::t ;;
This expression has type 'a list but is here used with type 'a
Marsh Posté le 31-12-2005 à 20:01:10
Une fonction pour faire quoi ? Qu'est-ce que tu essaies de faire ?
t::q et q::t ne peuvent pas avoir de sens dans la même expression puisque t est de type 'a tandis que q est une liste de 'a. Si tu veux faire un tri bulle il va falloir t'y prendre autrement.
Marsh Posté le 31-12-2005 à 20:17:27
justement mais je n'arrive pas
ben par exemple j'ai une liste de mots et je veux les trier dans l'ordre alphabétique, c'est tout
Marsh Posté le 04-01-2006 à 22:12:45
bonjour,
je dois ecrire une fonction "est_en_vente" de type int->bool qui à un article représenté par son code associe vrai ou faux selon que l'article est ou non dans la liste , dans une liste du type [(code,nom,prix) ; (code2,nom2,prix2) ; (... , ... , ...) ]
ca donne
let liste_article = [(1,"crayon",5);(2,"stylo", 10)];; |
je teste :
est_en_vente liste_article 1;; |
ca marche mais le probleme est le type de ma fonction qui n'est pas int-> bool mais ('a * 'b * 'c) list -> 'a -> bool = <fun> ..
comment avoir ce type ?
Marsh Posté le 04-01-2006 à 22:36:35
La fonction que tu as écrite devrait être une fonction auxilliaire de est_en_vente.
exemple un peu différent de ta solution (pour que tu cherches un minimum ) :
Code :
|
(oui c'est un exemple un peu bizarre, je sais )
PS : si tu ne connais pas : http://www.pps.jussieu.fr/Livres/ora/DA-OCAML/
Marsh Posté le 04-01-2006 à 22:39:39
merci je vais regarder
oui je connais le site jai même fais l'erreur d'acheter le bouquin alors qu'il est en integralité sur internet..et ya rien de plus dans le bouquin..
edit : c'est bon j'ai compris, merci
Marsh Posté le 04-01-2006 à 23:05:02
par contre comment modifie-t-on en général que certains elements d'une liste et on renvoie la meme modifiée ?
je sais pas, par exemple ajouté 10 aux elements b d'une liste [(x,b);(y,b');(z,b'')]...
je pensais à
|
mais bon le probleme et qu'il y a un "list" de trop dans le type, ca devrait être val modif : ('a * int) list -> int -> ('a * int) list
merci d'avance pour votre aide.
edit : c'est bon c'etait juste une histoire de crochet et parenthese lol
Marsh Posté le 05-01-2006 à 22:32:13
rebonsoir,
je cherche à ecrire une fonction nvelle_heure qui a 2 parametres (x,y) et un retard z fait correspondre une nvelle heure d'arrivée (pour les trains par exemple)
on a ainsi nvelle_heure (x,y) z.
par exemple, nvelle_heure (10,15) 30 = (11,15) (ca se lit nvelle heure de 10h15 +30 min de retard = 11h15.
je dois donc trouver une fonction general pour nimporte quelle heure, mais jarrive pas a gerer les depassements (ya que 60 minutes dans une heure etc, jpeux pas avoir (11,75) par exemple, faut que ce soit (12,15) et cest chiant. jy arrive pour un retard maximum de 60 min, ca donne:
let nvelle_heure (x,y) z = if y+z>=60 then (x+1, y+(60-z)) else (x,y+z);; |
ce qui se lit si y+z superieur a 60 alors on ecrit (x+1, y+(60-z)), sinon on ecrit (x,y+z) et ca marche bien:
# nvelle_heure (10,15) 30;; |
mais pas au dela de 60 min de retard
# nvelle_heure (10,15) 70;; |
Après jai reussi a aller jusque moins de 120 min de retard mais bon..
let valabs x = if x>=0 then x else -x;; |
merci de votre aide...
Marsh Posté le 05-01-2006 à 23:51:49
atmakefka a écrit : par exemple, nvelle_heure (10,15) 30 = (11,15) (ca se lit nvelle heure de 10h15 +30 min de retard = 11h15. |
Citation : je dois donc trouver une fonction general pour nimporte quelle heure, mais jarrive pas a gerer les depassements (ya que 60 minutes dans une heure etc, jpeux pas avoir (11,75) par exemple, faut que ce soit (12,15) et cest chiant. |
Il suffit de faire une fonction récursive qui ajoute 1 à la valeur de l'heure et retranche 60 à la valeur des minutes jusqu'à ce que la valeur des minutes soit inférieure à 60.
Pense aussi à gérer correctement minuit (ie. nvelle_heure (23,15) 60 )
(note : il y a la fonction abs qui fait la même chose que ta fonction valabs, pas besoin de réinventer la roue )
Marsh Posté le 16-12-2005 à 20:04:05
Bonjour,
j´ai vraiment du mal a comprendre ce qu´est une fonction d´ordre superieur..
quelqu´un pourrait -il m´expliquer ?
j´apprend le ocaml et ça parle de ça mais j´ai pas vraiment compris...
par exemple en ocaml je comprends pas ce que fait :
let h = function f -> function y -> (f y) + y
et jai cherché sur google ce qu´etait une fonction d´ordre superieur, j'ai compris la def mais je comprends pas dans le langage
merci d´avance..