Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell类型的强制表示与它们的C对应项相同?_Haskell_Ghc_Representation_Coerce - Fatal编程技术网

Haskell类型的强制表示与它们的C对应项相同?

Haskell类型的强制表示与它们的C对应项相同?,haskell,ghc,representation,coerce,Haskell,Ghc,Representation,Coerce,如何确定Haskell类型在给定平台上是否具有等效的可强制实例 我刚刚在GHC7.8中被告知,这看起来很棒。在这种情况下,我想解决我的具体问题的一个同样好的问题是:有没有办法询问GHC关于哪对类型的a,b有一个可强制的ab实例(比如在当前平台上) 在我看来,要想在编译器和平台无关的程序中发挥作用,人们需要知道——最好是在编译时,但也可能在编写代码时明确知道——给定的可强制a b实例是否存在于给定的平台上,否则就需要使用较慢的非noop回退(我想是通过CPP) 后续问题:GHC提供功能有意义吗 c

如何确定Haskell类型在给定平台上是否具有等效的可强制实例

我刚刚在GHC7.8中被告知,这看起来很棒。在这种情况下,我想解决我的具体问题的一个同样好的问题是:有没有办法询问GHC关于哪对类型的
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的特定版本,“嘿,你只需要<