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

F# Discussion :

Petite question sur le typage des fonctions


Sujet :

F#

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 46
    Points : 57
    Points
    57
    Par défaut Petite question sur le typage des fonctions
    Bonjour,

    J'aimerai savoir pourquoi F# type la fonction (+) de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    val (+) : int -> int -> int
    et non pas quelque chose comme cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    val (+) : 'a -> 'a -> 'a when 'a : INumerics
    Ce qui est d'autant plus étrange qu'elle accepte parfaitement l'expression suivante:
    et qu'un langage comme haskell dont le comportement de la fonction (+) est similaire, la type de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (+) :: (Num a) => a -> a -> a

  2. #2
    Rédacteur/Modérateur

    Avatar de gorgonite
    Homme Profil pro
    Ingénieur d'études
    Inscrit en
    Décembre 2005
    Messages
    10 322
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur d'études
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2005
    Messages : 10 322
    Points : 18 679
    Points
    18 679
    Par défaut
    surcharge des opérateurs en F#, ça explique tout
    Evitez les MP pour les questions techniques... il y a des forums
    Contributions sur DVP : Mes Tutos | Mon Blog

  3. #3
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Le type de l'opérateur + est celui-là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    val inline (+) :
       ^a ->  ^b ->  ^c
        when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)
    Il faut qu'il existe une méthode statique + de type ^a * ^b -> ^c. Le caractère ^ indique que le type (peu importe lequel, mais un seul) doit être connu à la compilation. C'est donc différent de 'a où le type exact n'est pas forcément connu par le compilateur.

    Cela explique donc que 1+2, 3.2+1.4 et "hello "+"world" sont acceptés. Dans ton cas, tu n'as pas donné de contexte suffisant au compilateur pour savoir le type des arguments. Comme il ne pouvait pas deviner et qu'il avait besoin d'un type concret, il a utilisé le type par défaut. Ici, c'est int.

    Si tu définis une classe, tu as simplement besoin de définir la méthode (+) pour utiliser l'opérateur dessus. Il n'y a pas besoin de toutes les choses de INumerics.

  4. #4
    Membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2010
    Messages : 46
    Points : 57
    Points
    57
    Par défaut
    Citation Envoyé par LLB Voir le message
    Le type de l'opérateur + est celui-là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    val inline (+) :
       ^a ->  ^b ->  ^c
        when ( ^a or  ^b) : (static member ( + ) :  ^a *  ^b ->  ^c)
    Il faut qu'il existe une méthode statique + de type ^a * ^b -> ^c. Le caractère ^ indique que le type (peu importe lequel, mais un seul) doit être connu à la compilation. C'est donc différent de 'a où le type exact n'est pas forcément connu par le compilateur.

    Cela explique donc que 1+2, 3.2+1.4 et "hello "+"world" sont acceptés. Dans ton cas, tu n'as pas donné de contexte suffisant au compilateur pour savoir le type des arguments. Comme il ne pouvait pas deviner et qu'il avait besoin d'un type concret, il a utilisé le type par défaut. Ici, c'est int.

    Si tu définis une classe, tu as simplement besoin de définir la méthode (+) pour utiliser l'opérateur dessus. Il n'y a pas besoin de toutes les choses de INumerics.
    Je te remercie pour ta réponse

    Et dans le cas où je voudrais créer une fonction qui accepterait n'importe quel type numérique et sur lequel je voudrais faire des opérations arithmétique (addition, soustraction, etc), je dois m'y prendre comment ?

  5. #5
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Une solution est de marquer la fonction en inline. Ce ne sera pas compilée comme une vraie fonction, elle sera spécialisée à chaque appel. Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    > let inline dist x y = x * x + y * y |> float |> sqrt;;
     
    val inline dist :
       ^a ->  ^d -> float
        when  ^a : (static member ( * ) :  ^a *  ^a ->  ^b) and
             ( ^b or  ^c) : (static member ( + ) :  ^b *  ^c ->  ^e) and
              ^d : (static member ( * ) :  ^d *  ^d ->  ^c) and
              ^e : (static member op_Explicit :  ^e -> float)
     
    > dist 5 2;;
    val it : float = 5.385164807
     
    > dist 5.f 2.3f;;
    val it : float = 5.503635142
    Les types ont tendance à devenir rapidement énormes. Il ne faut pas en abuser, mais c'est très utile dans certains cas (Seq.sum utilise ça par exemple).

    Tu peux aussi passer par l'interface INumerics comme tu demandes. Tu as une explication et un exemple ici : http://cs.hubfs.net/forums/permalink...read.aspx#3824 (note que la fonction GetNumericAssociation est maintenant dans le PowerPack)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Petite question sur la gestion des exception
    Par Wizard50 dans le forum C#
    Réponses: 1
    Dernier message: 05/05/2010, 10h17
  2. une petite question sur la texture des images
    Par katicr2 dans le forum Traitement d'images
    Réponses: 7
    Dernier message: 03/02/2010, 16h24
  3. petite question sur le format des dates
    Par sherdogvdb dans le forum Forms
    Réponses: 4
    Dernier message: 08/03/2007, 11h14
  4. Réponses: 3
    Dernier message: 21/10/2006, 17h03

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