未确定的泛型类型在 ghci 运行时中如何表示

发布于 2024-11-14 05:51:18 字数 832 浏览 0 评论 0原文

我很清楚泛型函数和泛型数据类型。

在泛型类型中:

data SB = forall x. (show x) => SB x
instance Show SB where
  show (SB x) = show x

因此对于任何给定类型 x,如果它具有 Show 签名,并且肯定有一个 show 函数与之对应。

但是当输入 ghci 时,例如,

:t 1

则输出

1 :: Num a => a

如果将 1 绑定到名称,

let a=1
:t a

:现在 a 具有真实类型。

问题是:

1在运行时系统中的形式是什么(在没有类型之前,它只有Num,因为它只能保存一些可以转换成的信息。

是否有一些内部功能可以将通用“信息”“打包”成真实的东西?

据我现在所知,在 haskell 中,一些真实的东西应该有“通用”标签,但不应该有一些“纯通用的东西”。

问候!

可能的结果:

reference to `1` becomes:
get_const_value_1 :: (Num a) => a
get_const_value_1 = fromIntegral (1 :: Integer)

I'm clear about the generic functions and generic data-types.

In the generic type:

data SB = forall x. (show x) => SB x
instance Show SB where
  show (SB x) = show x

so for any given type x, if it has a signature of Show, and there sure be a show function corresponds to it.

but when typing in ghci, e.g.

:t 1

outputs

1 :: Num a => a

if binds 1 to a name:

let a=1
:t a

now a has a true type.

The question is:

What is 1's form in the run-time system(before it has a type, it has only Num), since it can only hold some info of what it can be transformed to.

Are there some internal functions for 'packing up' the generic 'information' into real things?

For all that I know now, In haskell there should be 'generic' tags on some real things, but there should not be some 'pure generic things'.

Regards!

possible result:

reference to `1` becomes:
get_const_value_1 :: (Num a) => a
get_const_value_1 = fromIntegral (1 :: Integer)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2024-11-21 05:51:18

正如 Don Stewart 所说,GHC 中的类型类是使用“字典”实现的。 类型类 Num 被表示为函数记录(我将在这里跳过 EqShow 约束):

class Num a where
    fromInteger :: Integer -> a
    ...

这意味着

data Num a = Num { fromInteger :: Integer -> a, ... }

当您定义实例时,会使用实例中的函数创建一条新记录:

instance Num Integer where
    fromInteger = id
    ...

现在

numDictForInteger = Num { fromInteger = id, ... }

,当您在多态上下文中使用此函数时,编译器不知道要使用哪个字典,因此它会为其生成一个额外的参数:

foo :: Num a => a
foo = 1

变为

foo :: Num a -> a
foo numDict = fromInteger numDict 1

注意约束 Num a => 成为参数Num a ->


但是,当您删除多态性时,编译器知道要静态使用哪个字典,因此它会继续内联它而不是生成参数:

foo :: Integer
foo = 1

成为

foo :: Integer
foo = fromInteger numDictForInteger 1

作为脚注,这就是单态性限制存在的原因。多态值不会是 CAF,因为它需要字典参数。这可能会导致性能特征与您预期的显着不同,因此您必须明确声明此行为是您想要的。

As Don Stewart said, type classes in GHC are implemented using "dictionaries". That means that the type class Num is represented as a record of functions (I'm gonna skip the Eq and Show constraints here):

class Num a where
    fromInteger :: Integer -> a
    ...

becomes

data Num a = Num { fromInteger :: Integer -> a, ... }

When you define an instance, a new record is created with the functions from the instance:

instance Num Integer where
    fromInteger = id
    ...

becomes

numDictForInteger = Num { fromInteger = id, ... }

Now, when you use this function in a polymorphic context, the compiler doesn't know which dictionary to use, so it generates an extra parameter for it:

foo :: Num a => a
foo = 1

becomes

foo :: Num a -> a
foo numDict = fromInteger numDict 1

Notice how the constraint Num a => becomes a parameter Num a ->.


However, when you remove the polymorphism, the compiler knows which dictionary to use statically, so it goes ahead and inlines it instead of generating a parameter:

foo :: Integer
foo = 1

becomes

foo :: Integer
foo = fromInteger numDictForInteger 1

As a footnote, this is why the monomorphism restriction exists. A polymorphic value would not be a CAF since it requires the dictionary argument. This might cause significantly different performance characteristics from what you might expect and therefore you're forced to explicitly state that this behavior is what you wanted.

情话难免假 2024-11-21 05:51:18

通过类型类参数化的通用函数在 GHC 中表示为采用“字典”的函数。这是一个数据结构,在实例化为给定类型时,包含特定类型类实例的所有方法。

因此,正如我们在 Haskell 中的类型类方法中所说,函数可能是泛型的(或“多态的”)。

有关 GHC 在运行时表示值的更多信息,请参阅:

Generic functions that are paramaterized via a type class are represented in GHC as functions that take a "dictionary". This is a data structure containing all the methods of a particular typeclass instance, when instantiated to a given type.

Thus functions may be generic (or "polymorphic") as we say in Haskell, in the typeclass methods.

For more about GHC's representation of values at runtime, see:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文