Précédent   Forum du club des développeurs et IT Pro > Autres langages > Langages fonctionnels > F#
F# Forum d'entraide sur la programmation en langage fonctionnel F#
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 12/07/2010, 15h23   #1
Dim Me As New Idiot
Membre du Club
 
Homme
Inscription : janvier 2010
Messages : 46
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : janvier 2010
Messages : 46
Points : 48
Points : 48
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 :
val (+) : int -> int -> int
et non pas quelque chose comme cela:
Code :
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 :
(+) :: (Num a) => a -> a -> a
Dim Me As New Idiot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2010, 20h37   #2
gorgonite
Rédacteur/Modérateur

 
Avatar de gorgonite
 
Homme Nicolas Vallée
Ingénieur d'études
Inscription : décembre 2005
Messages : 9 961
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Vallée
Âge : 28
Localisation : France

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

Informations forums :
Inscription : décembre 2005
Messages : 9 961
Points : 18 152
Points : 18 152
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
gorgonite est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2010, 00h44   #3
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 962
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 962
Points : 1 148
Points : 1 148
Le type de l'opérateur + est celui-là :
Code :
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.
LLB est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 13/07/2010, 09h24   #4
Dim Me As New Idiot
Membre du Club
 
Homme
Inscription : janvier 2010
Messages : 46
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations forums :
Inscription : janvier 2010
Messages : 46
Points : 48
Points : 48
Citation:
Envoyé par LLB Voir le message
Le type de l'opérateur + est celui-là :
Code :
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 ?
Dim Me As New Idiot est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/07/2010, 10h41   #5
LLB
Membre Expert
 
Inscription : mars 2002
Messages : 962
Détails du profil
Informations forums :
Inscription : mars 2002
Messages : 962
Points : 1 148
Points : 1 148
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 :
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)
LLB est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 14h32.


 
 
 
 
Partenaires

Hébergement Web