Dans le module, System.Info
je vois ces fonctions:
os :: String
arch :: String
compilerName :: String
compilerVersion :: Version
Pourquoi n'y en 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"
IO
, il y a un wrapperuname(3)
disponible sur Hackage: hackage.haskell.org/package/bindings-unameLa 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 casse si vous les traitez comme des constantes. Et il est plus pratique d'utiliser une constante simple qu'une action d'E / S.
Mais c'est une sorte de raisonnement hérité. Haskell est une vieille langue. (Non vraiment, il est plus ancien que Java de plusieurs années.) De nombreuses 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 d'E / S 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 d'E / S, bien qu'il existe encore quelques exceptions notables, comme le
Int
changement de 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.
la source
EDIT: Merci à @interjay et @Antal Spector-Zabusky pour avoir expliqué pourquoi cette réponse est rejetée. Ils ont écrit
Il dispose actuellement de deux votes de suppression. Je vais laisser ce processus suivre son cours, mais je suggère qu'il a en fait une certaine valeur. D'un côté, leurs explications montrent que la question était faible, tout comme les réponses, car un débutant Haskell pourrait facilement suivre le raisonnement que j'ai fait.
Réponse originale:
Je ne suis pas un programmeur Haskell, mais les deux réponses déjà données ne correspondent pas à la documentation liée par l'OP.
Mon interprétation de la documentation suit.
os :: String
- Cela vous donne "Le système d'exploitation sur lequel le programme s'exécute."Je m'attends à ce que cela émette un appel système pour obtenir les informations. Étant donné que le système sur lequel le programme est compilé peut être différent de celui sur lequel il s'exécute, il ne peut pas s'agir d'une valeur insérée par le compilateur. Si le code est interprété, l'interpréteur peut fournir le résultat, qui doit être obtenu via un appel système.
arch :: String
- Cela vous donne "l'architecture de la machine sur laquelle le programme s'exécute."Encore une fois, je m'attends à ce que cela émette un appel système pour obtenir les informations. Étant donné que le système sur lequel le programme est compilé peut être différent de celui sur lequel il s'exécute, il ne peut pas s'agir d'une valeur insérée par le compilateur.
compilerName :: String
- Cela vous donne "L'implémentation Haskell avec laquelle le programme a été compilé ou est en cours d'interprétation."Cette valeur est certainement insérée par le compilateur / interprète.
compilerVersion :: String
- Cela vous donne "La versioncompilerName
avec laquelle le programme a été compilé ou est en cours d'interprétation."Cette valeur est certainement insérée par le compilateur / interprète.
Bien que vous puissiez considérer que les deux premiers appels obtiennent une entrée, le résultat provient des valeurs détenues par le système d'exploitation. Les E / S font généralement référence à l'accès au stockage secondaire.
la source
IO
monade pour émuler l'état, émuler la séquence des opérationsos :: String
afin qu'elle fasse un appel système lorsqu'elle est évaluée.os
etarch
sont obtenus au moment de l'exécution.