Im Modul System.Info
sehe ich folgende Funktionen:
os :: String
arch :: String
compilerName :: String
compilerVersion :: Version
Warum gibt es dort keine IO
? Sie greifen auf das System zu ... irre ich mich? Meine Erwartung war ungefähr so:
os :: IO String
arch :: IO String
compilerName :: IO String
compilerVersion :: IO Version
Anwendungsfall:
print os -- "darwin"
print arch -- "x86_64"
print compilerName -- "ghc"
IO
, gibtuname(3)
es auf Hackage einen Wrapper : hackage.haskell.org/package/bindings-unameDie Frage ist gut. Die Antwort ist, wie es ist, dass diese Werte pro Programmkompilierung statisch sind. Sie werden im Wesentlichen in das Programm kompiliert und ändern sich danach nie mehr. Als solches bricht nichts (in den von GHC verwendeten Annahmen), wenn Sie sie als Konstanten behandeln. Und es ist bequemer, eine einfache Konstante als eine E / A-Aktion zu verwenden.
Aber das ist alles eine Art Legacy-Argumentation. Haskell ist eine alte Sprache. (Nein, es ist einige Jahre älter als Java.) Viele Bibliotheken wurden mit Argumenten erstellt, die nicht mehr als Best Practices gelten. Dies sind Beispiele dafür. Eine moderne Bibliothek, die sie verfügbar macht, würde sie wahrscheinlich zu E / A-Aktionen machen, obwohl sich die Ergebnisse nach der Kompilierung nicht ändern. Es ist nützlicher, Dinge, die keine Konstanten sind, auf der Quellenebene hinter E / A-Aktionen zu setzen, obwohl es immer noch einige bemerkenswerte Ausnahmen gibt, wie das
Int
Ändern der Größe zwischen 32- und 64-Bit-Plattformen.Auf jeden Fall ... Ich würde sagen, Ihre Erwartungen sind solide und diese Typen sind das Ergebnis historischer Kuriositäten.
quelle
EDIT: Vielen Dank an @interjay und @Antal Spector-Zabusky für die Erklärung, warum diese Antwort abgelehnt wird. Sie schrieben
Es hat derzeit zwei Löschstimmen. Ich werde diesen Prozess seinen Lauf nehmen lassen, aber vorschlagen, dass er tatsächlich einen gewissen Wert hat. Nebenbei bemerkt, ihre Erklärungen zeigen, dass die Frage schwach war, ebenso wie die Antworten, da ein Haskell-Neuling leicht der Argumentation folgen konnte, die ich gemacht habe.
Ursprüngliche Antwort:
Ich bin kein Haskell-Programmierer, aber die beiden bereits gegebenen Antworten stimmen nicht mit der Dokumentation überein, die das OP verknüpft hat.
Meine Interpretation der Dokumentation folgt.
os :: String
- Dies gibt Ihnen "Das Betriebssystem, auf dem das Programm ausgeführt wird."Ich gehe davon aus, dass dies einen Systemaufruf auslöst, um die Informationen zu erhalten. Da sich das System, auf dem das Programm kompiliert wird, möglicherweise von dem unterscheidet, auf dem es ausgeführt wird, kann es kein vom Compiler eingefügter Wert sein. Wenn der Code interpretiert wird, kann der Interpreter das Ergebnis bereitstellen, das über einen Systemaufruf abgerufen werden muss.
arch :: String
- Dies gibt Ihnen "Die Maschinenarchitektur, auf der das Programm ausgeführt wird."Auch hier erwarte ich, dass dies einen Systemaufruf auslöst, um die Informationen zu erhalten. Da sich das System, auf dem das Programm kompiliert wird, möglicherweise von dem unterscheidet, auf dem es ausgeführt wird, kann es kein vom Compiler eingefügter Wert sein.
compilerName :: String
- Dies gibt Ihnen "Die Haskell-Implementierung, mit der das Programm kompiliert wurde oder interpretiert wird."Dieser Wert wird sicherlich vom Compiler / Interpreter eingefügt.
compilerVersion :: String
- Dies gibt Ihnen "Die Version,compilerName
mit der das Programm kompiliert wurde oder interpretiert wird."Dieser Wert wird sicherlich vom Compiler / Interpreter eingefügt.
Während Sie möglicherweise davon ausgehen, dass die ersten beiden Aufrufe Eingaben erhalten, stammen die Ergebnisse aus Werten, die vom Betriebssystem gehalten werden. E / A bezieht sich im Allgemeinen auf den sekundären Speicherzugriff.
quelle
IO
Monade verwenden, um den Zustand zu emulieren, die Sequenz von Operationen zu emulierenos :: String
, sie so zu implementieren , dass sie bei der Auswertung einen Systemaufruf ausführt.os
undarch
werden zur Laufzeit erhalten.