- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在GHC.Prim
中,我们发现了一个名为dataToTag#的神奇函数。 :
dataToTag# :: a -> Int#
它根据它使用的数据构造函数将任何类型的值转换为整数。这用于加速 Eq
、Ord
和 Enum
的派生实现。在 GHC 源中,docs for dataToTag#
解释该参数应该已经被评估:
The dataToTag# primop should always be applied to an evaluated argument. The way to ensure this is to invoke it via the 'getTag' wrapper in GHC.Base:
getTag :: a -> Int#
getTag !x = dataToTag# x
对我来说,我们需要在调用 dataToTag#
之前强制 x
进行评估,这对我来说是完全有意义的。我不明白的是为什么刘海图案就足够了。 getTag
的定义只是语法糖:
getTag :: a -> Int#
getTag x = x `seq` dataToTag# x
但是让我们转向 docs for seq :
A note on evaluation order: the expression
seq a b
does not guarantee that a will be evaluated before b. The only guarantee given by seq is that the both a and b will be evaluated before seq returns a value. In particular, this means that b may be evaluated before a. If you need to guarantee a specific order of evaluation, you must use the function pseq from the "parallel" package.
在 parallel
包的 Control.Parallel
模块中,文档 elaborate further :
... seq is strict in both its arguments, so the compiler may, for example, rearrange
a `seq` b
intob `seq` a `seq` b
...
考虑到 seq
不足以控制计算顺序,如何保证 getTag
正常工作?
最佳答案
GHC 跟踪有关每个 primop 的某些信息。一个关键数据是primop是否“can_fail”。该标志的原始含义是,如果 primop 可能导致硬故障,则它可能会失败。例如,如果索引超出范围,数组索引可能会导致段错误,因此索引操作可能会失败。
如果 primop 可能失败,GHC 将限制它周围的某些转换,特别是不会将其从任何 case
表达式中 float 。例如,如果
if n < bound
then unsafeIndex c n
else error "out of range"
编译为
case unsafeIndex v n of
!x -> if n < bound
then x
else error "out of range"
其中一个底部是异常(exception);另一个是段错误。
dataToTag#
被标记为 can_fail。所以 GHC 看到(在 Core 中)类似
getTag = \x -> case x of
y -> dataToTag# y
(注意case
在Core中是严格的。)因为dataToTag#
被标记为can_fail,所以它不会从任何case
中 float 出来> 表达式。
关于haskell - dataToTag 参数的严格性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45043009/
在GHC.Prim中,我们发现了一个名为dataToTag#的神奇函数。 : dataToTag# :: a -> Int# 它根据它使用的数据构造函数将任何类型的值转换为整数。这用于加速 Eq、Or
我是一名优秀的程序员,十分优秀!