在模块System.Info
中,我看到了这些功能:
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"
中对compilerName
的定义,这是最明显的。
http://hackage.haskell.org/package/base-4.12.0.0/docs/src/System.Info.html
甚至是compilerName :: String
compilerName = "ghc"
之类的东西>
os
是根据未定义的名称
os :: String os = HOST_OS
(以大写字母开头的值???来定义的,这表明它只是一个占位符,在安装过程中将被替换。
有人也可以纠正我(请!),但是该文件顶部的HOST_OS
编译指示建议在编译之前用C预处理程序将{-# LANGUAGE CPP #-}
等替换为适当的字符串。
这个问题是一个好问题。答案是这样的:每个程序编译这些值都是静态的。它们本质上已编译到程序中,此后再也不会更改。因此,如果将它们视为常量,则任何东西(在GHC使用的假设下)都不会中断。而且,使用简单的常量比执行IO操作更为方便。
我不是Haskell程序员,但是已经给出的两个答案与OP链接的文档不匹配。
真正的I / O操作通常涉及与某些外围设备的交互,大部分时间是由设备驱动程序通过硬件中断来处理的。这是一个复杂且相对缓慢的过程。