gpt4 book ai didi

haskell - 未装箱类型的限制

转载 作者:行者123 更新时间:2023-12-02 00:38:26 24 4
gpt4 key购买 nike

我想知道为什么 Haskell 中的未装箱类型有这些限制:

  1. 您无法为未装箱类型定义新类型:

    newtype Vec = Vec (# Float#, Float# #)

    但你可以定义类型同义词:

    type Vec = (# Float#, Float# #)
  2. 类型系列无法返回未装箱的类型:

    type family Unbox (a :: *) :: # where
    Unbox Int = Int#
    Unbox Word = Word#
    Unbox Float = Float#
    Unbox Double = Double#
    Unbox Char = Char#

这背后是否有一些根本原因,或者只是因为没有人要求此功能?

最佳答案

Haskell 中的参数多态性依赖于 t :: * 的所有值类型统一表示为指向运行时对象的指针。因此,相同的机器代码适用于多态值的所有实例。

对比 Rust 或 C++ 中的多态函数。例如,那里的恒等函数仍然具有类似于 forall a. a -> a 的类型。 ,但由于 a 的值不同类型可能有不同的大小,编译器必须为每个实例生成不同的代码。这也意味着我们无法在运行时框中传递多态函数:

data Id = Id (forall a. a -> a)

因为这样的函数必须能够正确地处理任意大小的对象。它需要一些额外的基础设施来允许此功能,例如我们可能需要运行时 forall a. a -> a函数需要额外的隐式参数,这些参数携带有关 a 的大小和构造函数/析构函数的信息值(value)观。

现在,newtype Vec = Vec (# Float#, Float# #) 的问题即使 Vec有样* ,需要某些 t :: * 值的运行时代码无法处理它。它是一对堆栈分配的 float ,而不是指向 Haskell 对象的指针,将其传递给期望 Haskell 对象的代码会导致段错误或错误。

一般(# a, b #)不一定是指针大小的,因此我们不能将其复制到指针大小的数据字段中。

类型家庭返回#由于相关原因,不允许使用类型。考虑以下因素:

type family Foo (a :: *) :: # where
Foo Int = Int#
Foo a = (# Int#, Int# #)

data Box = forall (a :: *). Box (Foo a)

我们的Box是不可表示的运行时,因为 Foo a对于不同的 a 有不同的尺寸-s。一般来说,多态性超过 #需要为不同的实例化生成不同的代码,就像在 Rust 中一样,但这与常规参数多态性相互作用很差,并使多态值的运行时表示变得困难,因此 GHC 不关心这些。

(并不是说不可能设计出可用的实现)

关于haskell - 未装箱类型的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33753397/

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