我试图弄清楚mVars是如何工作的,我偶然发现了这段代码:
-- |Create an 'MVar' which is initially empty.
newEmptyMVar :: IO (MVar a)
newEmptyMVar = IO $ \ s# ->
case newMVar# s# of
(# s2#, svar# #) -> (# s2#, MVar svar# #)
Run Code Online (Sandbox Code Playgroud)
除了混淆地相互递归之外newMVar,它还充满了哈希(#).
在两者之间,我无法弄清楚它是如何工作的.我知道这基本上只是mVar的伪构造函数,但模块的其余部分(实际上大部分库)都包含它们,我找不到它们.谷歌搜索"Haskell哈希"并没有产生任何相关的东西.
Dan*_*zer 19
他们(字面上)是魔法哈希.它们区分GHC的原语,如添加,未装箱类型和未装箱的元组.你可以用它来编写它们
{-# LANGUAGE MagicHash #-}
Run Code Online (Sandbox Code Playgroud)
现在您可以导入允许您使用它们的存根
import GHC.Exts
unboxed :: Int# -> Int# -> Int#
unboxed a# b# = a# +# b#
boxed :: Int -> Int -> Int
boxed (I# a#) (I# b#) = I# (unboxed a# b#)
Run Code Online (Sandbox Code Playgroud)
当你想到它时,这实际上有点漂亮,通过包装像这样的神奇和严格的原语,我们可以在运行时系统级别统一处理惰性Int和Chars.
因为原语不是盒装的,所以它们在种类层面上是分开的.这意味着Int#没有*像普通类型那样的东西,这也意味着类似的东西
kindClash :: Int# -> Int#
kindClash = id -- id expects boxed types
Run Code Online (Sandbox Code Playgroud)
不会编译.
要进一步详细说明您的代码,newMVar请在GHC中调用编译器原语以分配新的可变变量.与编译器调用的瘦包装器不同,它不是相互递归的.因为我们把它IO视为一个反常状态的monad,所以在这个函数的角落也有一些黑暗聚集,但是我们不要密切关注它.我非常喜欢我的理智.
我不会在日常代码中使用原语,也不应该使用原语.它们在实现疯狂优化热点时出现,或者接近原始抽象,例如您正在查看的内容.