"MutVar#"是什么意思?

3

我一直在尝试阅读和理解实现Haskell的ST单子的代码,并发现了这个代码

{-# LANGUAGE Unsafe #-}
{-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples #-}
{-# OPTIONS_HADDOCK hide #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.STRef
-- Copyright   :  (c) The University of Glasgow, 1994-2002
-- License     :  see libraries/base/LICENSE
--
-- Maintainer  :  cvs-ghc@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC Extensions)
--
-- References in the 'ST' monad.
--
-----------------------------------------------------------------------------

module GHC.STRef (
        STRef(..),
        newSTRef, readSTRef, writeSTRef
    ) where

import GHC.ST
import GHC.Base

data STRef s a = STRef (MutVar# s a)
-- ^ a value of type @STRef s a@ is a mutable variable in state thread @s@,
-- containing a value of type @a@

-- |Build a new 'STRef' in the current state thread
newSTRef :: a -> ST s (STRef s a)
newSTRef init = ST $ \s1# ->
    case newMutVar# init s1#            of { (# s2#, var# #) ->
    (# s2#, STRef var# #) }

-- |Read the value of an 'STRef'
readSTRef :: STRef s a -> ST s a
readSTRef (STRef var#) = ST $ \s1# -> readMutVar# var# s1#

-- |Write a new value into an 'STRef'
writeSTRef :: STRef s a -> a -> ST s ()
writeSTRef (STRef var#) val = ST $ \s1# ->
    case writeMutVar# var# val s1#      of { s2# ->
    (# s2#, () #) }

-- Just pointer equality on mutable references:
instance Eq (STRef s a) where
    STRef v1# == STRef v2# = isTrue# (sameMutVar# v1# v2#)

我在上面的代码文件中看到以下代码行:

我在上面的代码文件中看到以下代码行:

data STRef s a = STRef (MutVar# s a)

MutVar#上进行快速搜索得到以下结果: 我的问题是: 什么是MutVar#?为什么它没有定义在任何地方?它的意思是什么?

1
它似乎是一个原始类型在GHC中定义。这是用于IORef的相同类型,其中s类型参数设置为RealWorld# - Cactus
它确实被定义在某个地方:在GHC.Prim中。但是定义只是一个空白存根;正如其他人所说,真正的实现已经硬编码到编译器中了。这是一个低级别的 GHC 特定实现细节。不同的 Haskell 编译器可能会以不同的方式实现它。 - MathematicalOrchid
1个回答

7

MutVar#是编译器提供的原始类型,代表可变引用,并构成了IORefSTRef的核心。

一般来说,任何以#结尾的内容都是 GHC 的实现细节。除非你在进行低级处理,否则无需担心它们。大多数这些操作都有包装器(比如ST),更易于使用。

你可以在GHC手册ghc-prim包中阅读更多相关信息。


2
事实上,任何 ____# 名称都是原始类型,例如 Int# 等。您需要 {-# LANGUAGE MagicHash #-} 来启用它。 - AJF
@AJFarmar 注意措辞。 “所有___#名称都是原始的”只是一种约定,它并没有被编译器实际执行。您可以定义以“#”结尾的自己的函数和类型,GHC不会对它们进行任何区别处理。 - Lambda Fairy
没错,但是 Haskell 中的规范被遵循得相当好!尽管如此,这也值得一提。 - AJF

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接