В модуле System.Info
я вижу эти функции:
os :: String
arch :: String
compilerName :: String
compilerVersion :: Version
Почему там нет IO
? Они получают доступ к системе ... Я ошибаюсь? Мое ожидание было что-то вроде:
os :: IO String
arch :: IO String
compilerName :: IO String
compilerVersion :: IO Version
Случай использования:
print os -- "darwin"
print arch -- "x86_64"
print compilerName -- "ghc"
IO
там было что-то, есть обертка вокругuname(3)
Hackage: hackage.haskell.org/package/bindings-unameВопрос хороший. Ответ, как бы то ни было, заключается в том, что эти значения являются статическими для каждой программы компиляции. Они по сути компилируются в программу и после этого никогда не меняются. Таким образом, ничто (в допущениях, используемых GHC) не нарушается, если вы рассматриваете их как константы. И удобнее использовать простую константу, чем действие ввода-вывода.
Но это все виды устаревших рассуждений. Хаскель это старый язык. (Нет, на несколько лет он старше, чем Java.) Было создано много библиотек, основанных на рассуждениях, которые больше не считаются лучшими практиками. Это примеры этого. Современная библиотека, разоблачающая их, вероятно, сделает их действиями ввода-вывода, даже если результаты не изменятся после компиляции. Более полезно помещать вещи, которые не являются константами на уровне источника, за действиями ввода-вывода, хотя есть все еще некоторые заметные исключения, такие как
Int
изменение размера между 32- и 64-битными платформами.В любом случае ... я бы сказал, что ваши ожидания солидны, и эти типы являются результатом исторических странностей.
источник
РЕДАКТИРОВАТЬ: Спасибо @interjay и @Antal Spector-Zabusky за объяснение, почему этот ответ опровергается. Они написали
В настоящее время он имеет два голоса для удаления. Я позволю этому процессу идти своим чередом, но предполагаю, что он действительно имеет определенную ценность. С другой стороны, их объяснения показывают, что вопрос был слабым, как и ответы, так как новичок из Хаскелла мог легко следовать рассуждениям, которые я сделал.
Оригинальный ответ:
Я не программист на Haskell, но оба ответа уже не соответствуют документации, которую связал OP.
Моя интерпретация документации следующая.
os :: String
- Это дает вам «Операционная система, в которой работает программа».Я ожидаю, что это выдаст системный вызов для получения информации. Поскольку система, в которой скомпилирована программа, может отличаться от той, в которой она выполняется, она не может быть значением, вставленным компилятором. Если код интерпретируется, то интерпретатор может предоставить результат, который должен быть получен с помощью системного вызова.
arch :: String
- Это дает вам «Архитектуру машины, на которой работает программа».Опять же, я ожидаю, что это вызовет системный вызов для получения информации. Поскольку система, в которой скомпилирована программа, может отличаться от той, в которой она выполняется, она не может быть значением, вставленным компилятором.
compilerName :: String
- Это дает вам «реализацию на Haskell, с помощью которой программа была скомпилирована или интерпретируется».Это значение, безусловно, вставляется компилятором / интерпретатором.
compilerVersion :: String
- Это дает вам «версию,compilerName
с которой программа была скомпилирована или интерпретируется».Это значение, безусловно, вставляется компилятором / интерпретатором.
Хотя вы можете считать, что первые два вызова получают входные данные, результат получается из значений, хранящихся в операционной системе. Обычно ввод-вывод относится к доступу к вторичной памяти.
источник
IO
монаду, чтобы эмулировать состояние, эмулировать последовательность операцийos :: String
системный вызов при оценке.os
иarch
получается во время выполнения.