web-dev-qa-db-fra.com

Pourquoi l'accès à System.Info n'est-il pas considéré comme une opération IO dans Haskell?

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"
25
Francisco Albert

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.

29
chepner

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.

19
Carl