Il y a en fait trois opérateurs de exponentiation: (^), (^^)et (**). ^est une exponentiation intégrale non négative, une exponentiation ^^entière et une exponentiation à **virgule flottante:
(^) :: (Num a, Integral b) => a -> b -> a
(^^) :: (Fractional a, Integral b) => a -> b -> a
(**) :: Floating a => a -> a -> a
La raison est la sécurité de type: les résultats des opérations numériques ont généralement le même type que le ou les arguments d'entrée. Mais vous ne pouvez pas élever an Intà une puissance à virgule flottante et obtenir un résultat de type Int. Et donc le système de type vous empêche de faire cela: (1::Int) ** 0.5produit une erreur de type. Il en va de même (1::Int) ^^ (-1).
Une autre façon de dire ceci: les Numtypes sont fermés sous ^(ils ne sont pas obligés d'avoir un inverse multiplicatif), les Fractionaltypes sont fermés sous ^^, les Floatingtypes sont fermés sous **. Puisqu'il n'y a pas d' Fractionalexemple pour Int, vous ne pouvez pas l'élever à une puissance négative.
Idéalement, le deuxième argument de ^serait statiquement contraint à être non négatif (actuellement, 1 ^ (-2)lève une exception d'exécution). Mais il n'y a pas de type pour les nombres naturels dans le Prelude.