IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Erreur d'utilisation de exp


Sujet :

Caml

  1. #1
    Candidat au Club
    Inscrit en
    Juin 2009
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 8
    Points : 3
    Points
    3
    Par défaut Erreur d'utilisation de exp
    Bonjour, me revoila avec un petit problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
            Objective Caml version 3.10.0
    
    # type expression= 
        Const of float
      | Exp of expression
    ;;
    let rec evaluer exp = match exp with
          Const c-> c
        | Exp f -> exp(evaluer f)
      ;;
    This expression is not a function, it cannot be applied
    C'est bizarre cette erreur surtout que je peux faire exp(3.);; .
    C'est du à la version d'ocaml que j'ai ?
    (j'ai réduit la fonction et le type pour clarifier)

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ca s'appelle du shadowing, littéralement tu mets la variable originale dans l'ombre, ici ton paramètre s'appelle "exp" donc il masque la fonction exp() pour la portée de ta fonction, autrement dit ton code est équivalent à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    let rec evaluer truc = match truc with
          Const c-> c
        | Exp f -> truc(evaluer f)
    Généralement on utilise e ou expr pour "expression", jamais "exp".

    --
    Jedaï

  3. #3
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Salut !

    J'ajoute au propos de Jedai que si, pour une raison quelconque, tu veux garder exp pour expression, il faut être plus explicite pour la fonction exponentielle et utiliser Pervasives.exp. Ton code devient alors :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    type expression = Const of float | Exp of expression
     
    let rec evaluer exp = match exp with
      | Const c -> c
      | Exp f -> Pervasives.exp (evaluer f)
    Ceci étant, on peut remplacer let rec evaluer exp = match exp with par let rec evaluer = function, ce qui évite de nommer l'argument. D'ailleurs tu n'en as pas besoin puisque exp est filtré et jamais réutilisé tel quel.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    type expression = Const of float | Exp of expression
    let rec evaluer = function Const c -> c | Exp f -> exp (evaluer f)
    Cordialement,
    Cacophrène

  4. #4
    Candidat au Club
    Inscrit en
    Juin 2009
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Ok c'est vrai que ça paraît evident maintenant. Merci pour le complement d'info.

  5. #5
    Candidat au Club
    Inscrit en
    Juin 2009
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Juin 2009
    Messages : 8
    Points : 3
    Points
    3
    Par défaut
    Et je voudrais savoir si c'était possible de faire quelque chose comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let opp  fonction= fun x -> let res = fonction x in -.res;; 
     
    let derive = fun 
      sin -> cos 
     |exp -> exp
     |cos -> opp sin
     ;;
       |exp -> exp
       ^
    Syntax error
    qui serait de type (float -> float) -> (float -> float) qui à une fonction retournerait une autre fonction. Un peu à la manière de opp.

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Non, ce n'est pas possible parce que ça impliquerait de comparer des fonctions, chose qu'on ne sait pas faire. Si tu veux faire des trucs comme ça, une solution serait de créer ton propre mini-langage intégré à OCaml pour faire du calcul symbolique (on appelle ça un DSL), ou de te reporter vers Haskell qui, bien qu'il ne te permette pas de comparer des fonctions, utilise un mécanisme de classes de type qui peut être utilisé pour faire des choses proches de ce que tu demandes (avec une méthode dite de dérivation automatique).

    --
    Jedaï

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Lala, c'est gore mais c'est pour le fun.

    Code ocaml : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # let sin, cos, exp = sin, cos, exp;;
     
    # let derive (f, signe) =
      let signe = signe = signe in
      if f == exp then (f, signe)
      else if f == sin then (cos, signe)
      else if f == cos then (sin, not signe)
      else invalid_arg "derive";;
    val derive : (float -> float) * 'a -> (float -> float) * bool = <fun>
     
    # applique (derive (fonction cos)) (2. *. atan 1.);;
    - : float = -1.

  8. #8
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Tu compares les adresses des fonctions, pas vraiment les fonctions elle-même, en plus c'est extrêmement limité, par exemple avec ton code tu ne peux dériver (fun x -> x^2 + 2)...

    Alors qu'avec la technique de différentiation automatique, ce genre de fonction ou plus complexe peut-être dérivée sans problème :
    Code Haskell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Prelude> import Data.Number.Dif
    Prelude Data.Number.Dif> let double = deriv (\x -> x^2)
    Prelude Data.Number.Dif> double 5
    10
    Prelude Data.Number.Dif> let f x = x^2 + 25
    Prelude Data.Number.Dif> f 3
    34
    Prelude Data.Number.Dif> deriv f 5
    10
    (Data.Number.Dif est un module relativement simple qui implémente les bases de la différentiation automatique)

    Tu peux même dériver des fonctions discontinues (avec des if dans l'expression), bien que la dérivée soit inexacte au point de discontinuité.

    --
    Jedaï

  9. #9
    Membre émérite
    Avatar de SpiceGuid
    Homme Profil pro
    Inscrit en
    Juin 2007
    Messages
    1 704
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 704
    Points : 2 991
    Points
    2 991
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let derive = fun 
      sin -> cos 
     |exp -> exp
     |cos -> opp sin
     ;;
    qui serait de type (float -> float) -> (float -> float) qui à une fonction retournerait une autre fonction.
    Ta fonction serait du type (sin | cos | exp | opp)(sin | cos | exp | opp),
    pas du type (float → float)(float → float).

    Autrement dit il y a un type somme (le type des fonctions dérivables) que tu n'as pas explicité.
    Commence par prouver que tes fonctions sont bien dérivables.
    Les fonctions float → float ne sont pas dérivables, elles sont justes applicables.

Discussions similaires

  1. [Mail] erreur avec utilisation fonction mail
    Par taka10 dans le forum Langage
    Réponses: 7
    Dernier message: 12/07/2006, 17h19
  2. Réponses: 6
    Dernier message: 03/07/2006, 09h26
  3. [FTP] Erreur d'utilisation de require_once
    Par dialydany dans le forum Langage
    Réponses: 14
    Dernier message: 06/11/2005, 18h46
  4. Réponses: 3
    Dernier message: 12/10/2005, 00h27
  5. Erreur en utilisation non-initialiser motif
    Par moniphal dans le forum Langage
    Réponses: 2
    Dernier message: 30/09/2005, 14h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo