gpt4 book ai didi

haskell - GHC 是否对存在类型使用动态调度?

转载 作者:行者123 更新时间:2023-12-04 22:27:32 27 4
gpt4 key购买 nike

以下代码是否使用 C++ 或 Java 中所理解的动态调度?

据我了解,在最后一行,编译器不可能在编译时知道要调用 (==) 的哪个实现,但是代码可以编译并产生正确的结果。
有人可以解释一下,这背后是什么样的实现(例如vptr)?

{-# LANGUAGE ExistentialQuantification #-}

data Value = A Int

data ForallFunc = forall a. Eq a => Forall (Value -> a)

unpackA (A int) = int

equalityTest :: Value -> Value -> ForallFunc -> Bool
equalityTest arg1 arg2 (Forall unpacker) =
let a1 = unpacker arg1
a2 = unpacker arg2 in
a1 == a2

最佳答案

大致,是的。
当您使用有界存在量化时,即当量化类型变量受某些约束 C a => ... 限制时然后 GHC 将在构造函数中存储一些指针,记住 C a 的方法以便以后在该构造函数上进行模式匹配时可以访问它们。
通常使用单个指针,很像 vptrvtable在许多 OOP 实现中。编译器也可以直接存储指向方法的指针,避免间接。我认为当类型类中只有一种方法时,这是由 GHC 完成的。当方法很少(比如两个)时也可以使用它——这会使每个值的内存占用更大,但访问速度更快。
所以,编译你的代码是粗略的,就好像约束被替换为 Eq字典,列出它的方法。那是:

data EqDict a = EqDict
{ eq :: a->a->Bool
, neq :: a->a->Bool }

data ForallFunc = forall a. Forall (EqDict a) (Value -> a)

unpackA (A int) = int

equalityTest :: Value -> Value -> ForallFunc -> Bool
equalityTest arg1 arg2 (Forall eqDict unpacker) =
let a1 = unpacker arg1
a2 = unpacker arg2 in
eq eqDict a1 a2
当然,编译构造函数调用 Forall someFunction大致是通过提供所需的 == 的实现来编译的。 , /=函数,它们的特定类型将被存在量化抽象掉。

关于haskell - GHC 是否对存在类型使用动态调度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49963134/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com