什么是库中的哈希(#)来源?

时间:2014-10-02 21:32:35

标签: haskell

我试图找出mVars是如何工作的,我偶然发现了这段代码:

-- |Create an 'MVar' which is initially empty.
newEmptyMVar  :: IO (MVar a)
newEmptyMVar = IO $ \ s# ->
    case newMVar# s# of
         (# s2#, svar# #) -> (# s2#, MVar svar# #)

除了与newMVar混淆地相互递归之外,它还充满了哈希(#)。

在两者之间,我无法弄清楚它是如何工作的。我知道这基本上只是mVar的伪构造函数,但模块的其余部分(实际上大部分库)都包含它们,我找不到它们。谷歌搜索“Haskell哈希”并没有产生任何相关的东西。

1 个答案:

答案 0 :(得分:19)

他们(字面上)魔法哈希。他们将GHC的原始特征与添加,未装箱类型和未装箱的元组区分开来。您可以使用

启用它们
{-# LANGUAGE MagicHash #-}

现在您可以import存根,可以将它们与

一起使用
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#)

当你想到它时,这实际上有点漂亮,通过包装像这样的神奇和严格的原语,我们可以在运行时系统级别统一处理惰性IntChar

因为原语不是盒装的,所以它们在种类层面上被隔离。这意味着Int#没有类似普通类型*的类型,这也意味着类似

kindClash :: Int# -> Int#
kindClash = id -- id expects boxed types

不会编译。

为了进一步详细说明您的代码,newMVar包括调用GHC中的编译器原语来分配新的可变变量。与编译器调用的瘦包装器不同,它不是相互递归的。因为我们将IO视为一个反常状态的monad,所以在这个函数的角落也会聚集一些黑暗,但是我们不要密切关注它。我非常喜欢我的理智。

我不会在日常代码中使用原语,也不应该使用原语。它们在实现疯狂优化热点时出现,或接近原始抽象,例如您正在查看的内容。