2 votes

Comment accéder aux éléments correctement dans son propre type défini en F#

Je viens tout juste de commencer à apprendre F# et je suis confus avec cet exercice scolaire. Veuillez m'excuser si c'est une question stupide, je n'ai pas pu trouver la réponse en cherchant. L'exercice me demande de :

L'ensemble des nombres complexes est l'ensemble des paires de nombres réels.

Définissez un type complex qui représente des nombres complexes avec des composantes en virgule flottante.

Définissez une fonction mkComplex : float -> float -> complex qui, étant donné deux nombres en virgule flottante, retourne le nombre complexe correspondant.

Définissez une fonction complexToPair : complex -> float * float qui, étant donné un nombre complexe (a,b), retourne la paire (a, b).

Voici ma tentative à ce sujet : tout d'abord, je définis le type complex :

type Complex = float * float

Je définis la fonction mkComplex :

let mkComplex a b = Complex (a, b)

La fonction complexToPair est celle qui me pose problème. Comment puis-je, étant donné le type complexe, accéder correctement aux éléments qui s'y trouvent? Le code suivant fonctionne sans problème mais j'obtiens une série d'erreurs de vérification de type.

let complexToPair (a: Complex) = (a.[0], a.[1])

a.[0] et a.[1] sont soulignés en rouge et me donnent le message suivant :

L'opérateur 'expr.[idx]' a été utilisé sur un objet de type indéterminé basé sur les informations antérieures à ce point du programme. Considérez l'ajout de contraintes de type supplémentaires.

Alors, qu'est-ce que je fais de travers? Le code fonctionne très bien.

2voto

Tomas Petricek Points 118959

La définition de type que vous utilisez est en train de définir un alias de type. Lorsque vous dites :

type Complex = float * float

Alors le type Complex est simplement un tuple. Vous pouvez créer ses valeurs en utilisant (1.0, 1.0). Lorsque vous avez une valeur c de ce type, vous pouvez accéder aux éléments en utilisant fst c et snd c, ou en utilisant la décomposition de motifs.

Utiliser un alias de type est parfois utile, mais je suppose que, dans ce cas, il serait plus souhaitable d'utiliser un union discrimité à un seul cas ou un record, c'est-à-dire :

type Complex = { a:float; b:float }       // Utilisation d'un record
type Complex = Complex of float * float   // Utilisation d'une union discrimée

La documentation sur les records F# explique tout ce que vous devez savoir sur l'utilisation des records. Pour les unions discriminées à un seul cas, vous pouvez vous référer à un article de la série Designing with Types sur F# for Fun and Profit.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X