哦,亲爱的。如果您查看 的定义numCapabilities
,您会发现它只是:
numCapabilities :: Int
numCapabilities = unsafePerformIO $ getNumCapabilities
以下 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
这绝对是不好的 - 的值numCapabilities
取决于何时对setNumCapabilities
程序中可能存在的任何调用进行评估。请注意,在第一个会话中,numCapabilities
保持一致,因为IO
仅在第一次评估时才执行。但是,在存在内联的情况下(名称未标记为 NOINLINE 或其他任何内容),即使这可能不是真的 - 原则上您可以从两次出现中获得两个不同的值numCapabilities
(尽管实际上我无法做到这一点发生)。
所以答案是它numCapabilities
不是一个纯函数,而是被臭名昭著的unsafePerformIO
.