Dans le module System.Info
Je vois ces fonctions:
os :: String
Arch :: String
compilerName :: String
compilerVersion :: Version
Pourquoi n'y a-t-il pas IO
? Ils accèdent au système ... Je me trompe? Mon attente était quelque chose comme:
os :: IO String
Arch :: IO String
compilerName :: IO String
compilerVersion :: IO Version
Cas d'utilisation:
print os -- "darwin"
print Arch -- "x86_64"
print compilerName -- "ghc"
Vous n'obtenez pas ces informations lors de l'exécution . Ils sont codés en dur dans le compilateur tel qu'il est installé sur votre système.
Ceci est plus évident si vous regardez la définition de compilerName
telle que trouvée dans http://hackage.haskell.org/package/base-4.12.0.0/docs/src/System.Info. html .
compilerName :: String
compilerName = "ghc"
mais même quelque chose comme os
os :: String
os = Host_OS
est défini en termes d'un nom par ailleurs non défini Host_OS
(une valeur commençant par une lettre majuscule ??) qui suggère qu'il ne s'agit que d'un espace réservé qui est remplacé lors de l'installation.
Quelqu'un peut aussi me corriger (s'il vous plaît!), Mais le {-# LANGUAGE CPP #-}
pragma en haut de ce fichier suggère que Host_OS
et similaires sont remplacés par des chaînes appropriées par le préprocesseur C avant la compilation.
La question est bonne. La réponse, telle qu'elle est, est que ces valeurs sont statiques par compilation de programme. Ils sont essentiellement compilés dans le programme et ne changent jamais après cela. En tant que tel, rien (dans les hypothèses utilisées par GHC) ne se brise si vous les traitez comme des constantes. Et il est plus pratique d'utiliser une constante simple qu'une action IO.
Mais c'est une sorte de raisonnement hérité. Haskell est une ancienne langue. (Non vraiment, il est plus ancien que Java de plusieurs années.) Beaucoup de bibliothèques ont été construites avec un raisonnement qui n'est plus considéré comme les meilleures pratiques. Ce sont des exemples de cela. Une bibliothèque moderne les exposant ferait probablement d'eux des actions IO même si les résultats ne changent pas après la compilation. Il est plus utile de placer des choses qui ne sont pas des constantes au niveau source derrière les actions IO, bien qu'il y ait encore quelques exceptions notables, comme Int
changer la taille entre les plates-formes 32 et 64 bits.
En tout cas ... je dirais que vos attentes sont solides, et ces types sont le résultat de bizarreries historiques.