hel*_*ami 21 haskell standard-library
在并发库GHC.Conc中有一个名为的函数numCapabilities.它的类型是numCapabilities :: Int,它实际上返回一些你通过命令行标志传递的数字(例如,5如果选项是+RTS -N 5).
但是,getArgs(type IO [String]:)基本上相同(它返回未解析的非运行时参数)但不是纯函数.
如果唯一借口是numCapabilities往往需要在纯代码,以什么方式不其他命令行选项不能在纯代码需要?
我缺少什么或者是numCapabilities设计缺陷还是我允许写下面的怪物?
myGetArgs = unsafePerformIO getArgs
Run Code Online (Sandbox Code Playgroud)
dfl*_*str 21
在这样的情况下,我看到了很多不同的观点.有些人认为编译之间可能不同的值不应该是纯粹的,有些人认为只要在程序的本地运行时(即在某些"配置"已经"设置"之后main)值没有改变,它应该是纯粹的.
该base包装似乎对中等地解决.numCapabilities 不会(据我所知)在运行期间改变,但getArgs 可能.
这是因为有一个withArgs函数可以改变你通过的args getArgs.所以,答案就是这样.
Ben*_*ood 15
哦,亲爱的.如果你看一下定义numCapabilities,你可以看到它只是:
numCapabilities :: Int
numCapabilities = unsafePerformIO $ getNumCapabilities
Run Code Online (Sandbox Code Playgroud)
以下ghci会话说明了问题:
[ben@euler ~]$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help
Loading [...]
ghci> :m +GHC.Conc
ghci> numCapabilities
1
ghci> setNumCapabilities 2
ghci> numCapabilities
1
ghci> :q
Leaving GHCi.
[ben@euler ~]$ ghci
GHCi, version 7.4.2: http://www.haskell.org/ghc/ :? for help
Loading [...]
ghci> :m +GHC.Conc
ghci> setNumCapabilities 2
ghci> numCapabilities
2
Run Code Online (Sandbox Code Playgroud)
这绝对是错误的 - 值numCapabilities取决于何时根据setNumCapabilities程序中可能存在的任何调用进行评估.请注意,在第一个会话中,numCapabilities保持一致,因为IO它仅在第一次评估时执行.然而,在内联的情况下(名称没有标记为NOINLINE或任何东西),即使这可能不是真的 - 你原则上可以从两次出现时获得两个不同的值numCapabilities(尽管在实践中我无法做到这一点)发生).
所以答案是,这numCapabilities 不是一个纯粹的功能,而是由臭名昭着的后门错误地标记出来的unsafePerformIO.