Haskell - Types et classe de type

Haskell est un langage fonctionnel et il est strictement typé, ce qui signifie que le type de données utilisé dans l'ensemble de l'application sera connu du compilateur au moment de la compilation.

Classe de type intégrée

Dans Haskell, chaque instruction est considérée comme une expression mathématique et la catégorie de cette expression est appelée Type. Vous pouvez dire que "Type" est le type de données de l'expression utilisée au moment de la compilation.

Pour en savoir plus sur le Type, nous utiliserons la commande ": t". De manière générique,Type peut être considéré comme une valeur, alors que Type Classpeut être considéré comme un ensemble de types similaires. Dans ce chapitre, nous découvrirons les différents types intégrés.

Int

Intest une classe de type représentant les données de types Integer. Chaque nombre entier compris entre 2147483647 et -2147483647 relève de laIntclasse de type. Dans l'exemple suivant, la fonctionfType() se comportera selon son type défini.

fType :: Int -> Int -> Int 
fType x y = x*x + y*y
main = print (fType 2 4)

Ici, nous avons défini le type de la fonction fType() comme int. La fonction prend deuxint valeurs et en renvoie un intvaleur. Si vous compilez et exécutez ce morceau de code, il produira la sortie suivante -

sh-4.3$ ghc -O2 --make *.hs -o main -threaded -rtsopts 
sh-4.3$ main
20

Entier

Integer peut être considéré comme un sur-ensemble de Int. Cette valeur n'est limitée par aucun nombre, par conséquent un entier peut être de n'importe quelle longueur sans aucune limitation. Pour voir la différence fondamentale entreInt et Integer types, modifions le code ci-dessus comme suit -

fType :: Int -> Int -> Int 
fType x y = x*x + y*y 
main = print (fType 212124454 44545454454554545445454544545)

Si vous compilez le morceau de code ci-dessus, le message d'erreur suivant sera généré -

main.hs:3:31: Warning:            
   Literal 44545454454554545445454544545 is out of the Int range -
   9223372036854775808..9223372036854775807 
Linking main ...

Cette erreur s'est produite car notre fonction fType () attend une valeur de type Int et nous transmettons une vraie grande valeur de type Int. Pour éviter cette erreur, modifions le type "Int" par "Integer" et observons la différence.

fType :: Integer -> Integer -> Integer 
fType x y = x*x + y*y 
main = print (fType 212124454 4454545445455454545445445454544545)

Maintenant, il produira la sortie suivante -

sh-4.3$ main
1984297512562793395882644631364297686099210302577374055141

Flotte

Jetez un œil au morceau de code suivant. Il montre comment fonctionne le type Float dans Haskell -

fType :: Float -> Float -> Float 
fType x y = x*x + y*y 
main = print (fType 2.5 3.8)

La fonction prend deux valeurs flottantes comme entrée et renvoie une autre valeur flottante comme sortie. Lorsque vous compilez et exécutez ce code, il produira la sortie suivante -

sh-4.3$ main
20.689999

Double

Doubleest un nombre à virgule flottante avec une double précision à la fin. Jetez un œil à l'exemple suivant -

fType :: Double -> Double -> Double 
fType x y = x*x + y*y 
main = print (fType 2.56 3.81)

Lorsque vous exécutez le morceau de code ci-dessus, il générera la sortie suivante -

sh-4.3$ main 
21.0697

Booléen

Boolest un type booléen. Cela peut être vrai ou faux. Exécutez le code suivant pour comprendre comment le type Bool fonctionne dans Haskell -

main = do  
   let x = True 
   
   if x == False 
      then putStrLn "X matches with Bool Type" 
   else putStrLn "X is not a Bool Type"

Ici, nous définissons une variable "x" comme un booléen et la comparons à une autre valeur booléenne pour vérifier son originalité. Il produira la sortie suivante -

sh-4.3$ main
X is not a Bool Type

Carboniser

Les caractères représentent les caractères. Tout ce qui se trouve dans un guillemet simple est considéré comme un personnage. Dans le code suivant, nous avons modifié notre précédentfType() pour accepter la valeur Char et renvoyer la valeur Char en sortie.

fType :: Char-> Char 
fType x = 'K' 
main = do  
   let x = 'v' 
   print (fType x)

Le morceau de code ci-dessus appellera fType() fonction avec un charvaleur de «v» mais renvoie une autre valeur de caractère, c'est-à-dire «K». Voici sa sortie -

sh-4.3$ main 
'K'

Notez que nous n'allons pas utiliser ces types explicitement car Haskell est suffisamment intelligent pour attraper le type avant qu'il ne soit déclaré. Dans les chapitres suivants de ce didacticiel, nous verrons comment différents types et classes de types font de Haskell un langage fortement typé.

Classe de type d'égaliseur

EQla classe type est une interface qui fournit la fonctionnalité pour tester l'égalité d'une expression. Toute classe Type qui souhaite vérifier l'égalité d'une expression doit faire partie de cette classe de type EQ.

Toutes les classes de type standard mentionnées ci-dessus en font partie EQclasse. Chaque fois que nous vérifions une égalité en utilisant l'un des types mentionnés ci-dessus, nous faisons en fait un appel àEQ classe de type.

Dans l'exemple suivant, nous utilisons le EQ Tapez en interne à l'aide de l'opération "==" ou "/ =".

main = do 
   if 8 /= 8 
      then putStrLn "The values are Equal" 
   else putStrLn "The values are not Equal"

Cela donnera la sortie suivante -

sh-4.3$ main 
The values are not Equal

Classe de type Ord

Ordest une autre classe d'interface qui nous donne la fonctionnalité de commande. Tous lestypes que nous avons utilisé jusqu'à présent en font partie Ordinterface. Comme l'interface EQ, l'interface Ord peut être appelée en utilisant ">", "<", "<=", "> =", "compare".

Veuillez trouver ci-dessous un exemple où nous avons utilisé la fonctionnalité de «comparaison» de cette classe de type.

main = print (4 <= 2)

Ici, le compilateur Haskell vérifiera si 4 est inférieur ou égal à 2. Comme ce n'est pas le cas, le code produira la sortie suivante -

sh-4.3$ main 
False

Spectacle

Showa une fonctionnalité pour imprimer son argument sous forme de chaîne. Quel que soit son argument, il imprime toujours le résultat sous forme de chaîne. Dans l'exemple suivant, nous imprimerons la liste entière en utilisant cette interface. "show" peut être utilisé pour appeler cette interface.

main = print (show [1..10])

Il produira la sortie suivante sur la console. Ici, les guillemets doubles indiquent qu'il s'agit d'une valeur de type String.

sh-4.3$ main 
"[1,2,3,4,5,6,7,8,9,10]"

Lis

Readl'interface fait la même chose que Show, mais elle n'imprimera pas le résultat au format String. Dans le code suivant, nous avons utilisé leread interface pour lire une valeur de chaîne et la convertir en une valeur Int.

main = print (readInt "12") 
readInt :: String -> Int 
readInt = read

Ici, nous passons une variable String ("12") au readIntméthode qui à son tour renvoie 12 (une valeur Int) après la conversion. Voici sa sortie -

sh-4.3$ main 
12

Enum

Enumest un autre type de classe Type qui active la fonctionnalité séquentielle ou ordonnée dans Haskell. Cette classe Type est accessible par des commandes telles queSucc, Pred, Bool, Char, etc.

Le code suivant montre comment trouver la valeur successeur de 12.

main = print (succ 12)

Il produira la sortie suivante -

sh-4.3$ main
13

Délimité

Tous les types ayant des limites supérieures et inférieures relèvent de cette classe de types. Par exemple,Int les données de type ont une limite maximale de "9223372036854775807" et une limite minimale de "-9223372036854775808".

Le code suivant montre comment Haskell détermine la limite maximale et minimale du type Int.

main = do 
   print (maxBound :: Int) 
   print (minBound :: Int)

Il produira la sortie suivante -

sh-4.3$ main
9223372036854775807
-9223372036854775808

Maintenant, essayez de trouver la limite maximale et minimale des types Char, Float et Bool.

Num

Cette classe de type est utilisée pour les opérations numériques. Les types tels que Int, Integer, Float et Double relèvent de cette classe Type. Jetez un œil au code suivant -

main = do 
   print(2 :: Int)  
   print(2 :: Float)

Il produira la sortie suivante -

sh-4.3$ main
2
2.0

Intégral

Integralpeut être considérée comme une sous-classe de la classe de type Num. La classe de type Num contient tous les types de nombres, tandis que la classe de type Integral n'est utilisée que pour les nombres entiers. Int et Integer sont les types de cette classe Type.

Flottant

Comme Integral, Floating fait également partie de la classe Num Type, mais il ne contient que des nombres à virgule flottante. Par conséquent,Float et Double relèvent de cette classe de type.

Classe de type personnalisé

Comme tout autre langage de programmation, Haskell permet aux développeurs de définir des types définis par l'utilisateur. Dans l'exemple suivant, nous allons créer un type défini par l'utilisateur et l'utiliser.

data Area = Circle Float Float Float  
surface :: Area -> Float   
surface (Circle _ _ r) = pi * r ^ 2   
main = print (surface $ Circle 10 20 10 )

Ici, nous avons créé un nouveau type appelé Area. Ensuite, nous utilisons ce type pour calculer l'aire d'un cercle. Dans l'exemple ci-dessus, "surface" est une fonction qui prendArea comme entrée et produit Float comme sortie.

Gardez à l'esprit que «data» est ici un mot-clé et que tous les types définis par l'utilisateur dans Haskell commencent toujours par une majuscule.

Il produira la sortie suivante -

sh-4.3$ main
314.15927