Haskell类型的强制表示与它们的C对应项相同?
如何确定Haskell类型在给定平台上是否具有等效的可强制实例 我刚刚在GHC7.8中被告知,这看起来很棒。在这种情况下,我想解决我的具体问题的一个同样好的问题是:有没有办法询问GHC关于哪对类型的Haskell类型的强制表示与它们的C对应项相同?,haskell,ghc,representation,coerce,Haskell,Ghc,Representation,Coerce,如何确定Haskell类型在给定平台上是否具有等效的可强制实例 我刚刚在GHC7.8中被告知,这看起来很棒。在这种情况下,我想解决我的具体问题的一个同样好的问题是:有没有办法询问GHC关于哪对类型的a,b有一个可强制的ab实例(比如在当前平台上) 在我看来,要想在编译器和平台无关的程序中发挥作用,人们需要知道——最好是在编译时,但也可能在编写代码时明确知道——给定的可强制a b实例是否存在于给定的平台上,否则就需要使用较慢的非noop回退(我想是通过CPP) 后续问题:GHC提供功能有意义吗 c
a
,b
有一个可强制的ab
实例(比如在当前平台上)
在我看来,要想在编译器和平台无关的程序中发挥作用,人们需要知道——最好是在编译时,但也可能在编写代码时明确知道——给定的可强制a b
实例是否存在于给定的平台上,否则就需要使用较慢的非noop回退(我想是通过CPP)
后续问题:GHC提供功能有意义吗
coerceOrConvert :: (a -> b) -> a -> b
具有强制转换f
为
如果当前GHC版本和平台存在可强制执行的a b实例强制执行
如果没有f
我意识到这对于普通的类型类来说没有什么意义,但是可强制的
似乎远不是普通的,所以我很难判断…通常,Haskell处理的强制有两种类型:表示平等(通过newtype
和可强制的)和关于类型变量的新信息(通过Typeable
)。第二种类型与运行时表示关系不大,因此我将只描述可强制的
/新类型
机制
它保证newtype
只更改类型信息而不更改底层表示,因此如果我们有(标准示例)
然后,我们应该能够确信
instance Num Age where
Age a + Age b = Age (a + b)
...
map Age :: [Int] -> [Age]
与Int
上的(+)
一样快,也就是说,在幕后没有进行指针间接寻址。事实上,GHC毫不费力地消除了年龄
构造函数。当我们想做类似的事情时,挑战就来了
instance Num Age where
Age a + Age b = Age (a + b)
...
map Age :: [Int] -> [Age]
由于Int
和Age
在结构上是相同的,因此这也应该是不可操作的——我们所要做的就是在编译时满足类型系统,然后在运行时在操作上丢弃map Age
。不幸的是,情况并非如此,因为map
即使在每次都不做任何操作,它仍然会遍历我们的列表年龄
在大量的newtype
s被抛出的情况下,我们还希望GHC生成您可能看到的最紧凑的编译代码(危险、小心地)使用unsafeccerce
unsafeCoerce :: [Int] -> [Age]
在这种情况下,unsacecoerce
是“安全的”,因为我们知道这两种类型在运行时是相同的。而且,由于unsacecoerce
纯粹在类型级别上运行,并且在运行时是一个真正的no-op,我们知道与map Age
不同,unsacecoerce
确实是一种O(0)
强制
但这相当危险
impolible
希望通过允许以下实例化来解决此问题
instance Coercible a b => Coercible [a] [b] where coerce = unsafeCoerce
因此,Haskell typeclass机制允许仅在安全的情况下使用强制
,而不像不安全
。为了确保这种情况,必须不可能构建可强制
的恶意实例。为此,所有可强制
实例都是由编译器基于n的使用而构建的ewtype
最后,当您真正深入了解可强制
的工作原理时,您必须了解新的Haskell角色系统,该系统允许开发人员注释新类型
是否应允许强制。这在[可强制
类的文档]中有明确概述().谢谢。这是一个非常有用的信息,但仍然存在一个问题:是否有一个(可能依赖于平台的)列表,或者(更好的)从GHC生成这样一个列表的方法,其中标准类型a
和b
有一个可强制a b
的例子?(我所说的“标准类型”可能是指“Haskell报告中指定的类型”,或其中的一些子集)。我将添加一个更具体的场景:修复具体的类型a
和b
。假设我想编写一个转换函数f::a->b
。我怀疑在许多平台上使用GHC,会有一个可强制的ab
实例,但不是在所有平台上都有(这可能会发生,对吗?)。假设还有一个通用的、缓慢的转换函数g::a->b
,它总是做正确的事情,而不对底层表示做任何假设(比如说g
在Haskell报告中)。我能(如果必须使用CPP)说“只要有一个可强制的ab实例,就让f=concurve
,否则就让f=g
"?我认为这是不可能的。Haskell报告保证了新类型具有相同的表示形式,但没有说明应该如何实现。你可以做GHC实现Haskell的特定事情——我认为如果你深入研究包的内部,你会看到很多,但这些事情往往非常复杂不安全。可强制
按设计独立于任何实际实施细节,它完全根据新类型
承诺工作。我确实在问GHC的具体实施情况,我理解可强制
独立于实施细节……我想我问的是:是否存在易于访问的列表,在某种程度上保证它不会在次要版本中更改,其中(标准)类型是在GHC中使用newtype
实现的?或者,也可以在特定平台上询问GHC的特定版本,“嘿,你只需要<