重写规则不会触发匹配多个实例方法的规则

编程入门 行业动态 更新时间:2024-10-23 17:38:06
本文介绍了重写规则不会触发匹配多个实例方法的规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

据我所知,我认为这不会有什么区别,id1和id2来自类型类,id1'和id2'不是。我正在使用最新的Haskell平台(GHC版本7.0.4和现在的7.4.1)运行ghc Rewrite,并且我希望1也能够启动。

<$重写重写编译RewriteProblems(Rewrite.hs,Rewrite.o)被解雇的规则:重写/ ez'被解雇的规则:重写/ to1'被解雇的规则:重写/ ez 被解雇的规则:重写/ ez 被解雇的规则:类操作id2 被解雇的规则:类操作id2

举例:

{ - #OPTIONS_GHC -O -ddump-rule-firingings# - } 模块RewriteProblems其中 { - #RULES rewrite / ezforall a。 id1 a = RDUnit rewrite / to1forall a。 id2(id2 a)= id1 a rewrite / ez'forall a。 id1'a = RDUnit rewrite / to1'forall a。 id2'(id2'a)= id1 a # - } class Ider a where id1 :: a - > a id2 :: a - > a data RewriteD = RDUnit 实例Ider重写D其中 { - #INLINE [1] id1# - } { - #INLINE [1 ] id2# - } id1 a = RDUnit id2 a = RDUnit testThing1 :: RewriteD testThing1 = id1 RDUnit testThing2 :: RewriteD testThing2 = id2(id2 RDUnit) testThing1':: RewriteD testThing1'= id1'RDUnit testThing2':: RewriteD testThing2'= id2'(id2'RDUnit) { - #INLINE [1] id1'# - } { - #INLINE [1] id2'# - } id1':: RewriteD - > RewriteD id2':: RewriteD - > RewriteD id1'a = RDUnit id2'a = RDUnit

解决方案

(在整篇文章中对更新信息进行了一些编辑)

在你的输出中,注意行 Rule fired:Class op id2 。这些是由GHC为类型实例自动创建的规则。这条规则是先发射,所以你自己的规则永远不会有机会匹配。如果使用-ddump-simpl-iterations进行编译,您可以检查Class op规则在第一阶段触发,之后您的to1规则永远不会匹配。

这是一个解决方法。首先注释掉 testThing1 , testThing1'和 testThing2'所以只编译 testThing2 。这是rewrite / to1可以触发的唯一函数,因此它隔离了您正在查看的测试用例。接下来添加另一个表单规则:

rewrite / to_id2'forall a。 id2 a = id2'a

,您将看到以下输出:

$ ghc -c foo.hs 规则解雇:rewrite / to_id2'规则解雇:rewrite / to_id2'规则被解雇:重写/ to1'被解雇的规则:重写/ ez

新规则是现在发射而不是类操作,它允许 rewrite / to1'来简化表达式。有趣的是,新规则在RULES列表中出现在 rewrite / to1 之上还是之下并不重要。

我不知道为什么你的 id2(id2 a)规则不匹配,而 id2 a 。它看起来应该匹配(根据-dverbose-core2core),但事实并非如此。我仍然怀疑某种类型的GHC优先级错误,尽管我也看到了与ghc-7.4.1相同的行为,所以它不是 4397 。

As far as I can tell I wouldn't think it would make any difference that id1 and id2 are from a type class and id1' and id2' are not. I am running "ghc Rewrite" with the latest Haskell Platform (with both GHC version 7.0.4 and now 7.4.1 too), and I expect to1 to also fire.

$ ghc Rewrite [1 of 1] Compiling RewriteProblems ( Rewrite.hs, Rewrite.o ) Rule fired: rewrite/ez' Rule fired: rewrite/to1' Rule fired: rewrite/ez Rule fired: rewrite/ez Rule fired: Class op id2 Rule fired: Class op id2

the example:

{-# OPTIONS_GHC -O -ddump-rule-firings #-} module RewriteProblems where {-# RULES "rewrite/ez" forall a. id1 a = RDUnit "rewrite/to1" forall a. id2 (id2 a) = id1 a "rewrite/ez'" forall a. id1' a = RDUnit "rewrite/to1'" forall a. id2' (id2' a) = id1 a #-} class Ider a where id1 :: a -> a id2 :: a -> a data RewriteD = RDUnit instance Ider RewriteD where {-# INLINE[1] id1 #-} {-# INLINE[1] id2 #-} id1 a = RDUnit id2 a = RDUnit testThing1 :: RewriteD testThing1 = id1 RDUnit testThing2 :: RewriteD testThing2 = id2 (id2 RDUnit) testThing1' :: RewriteD testThing1' = id1' RDUnit testThing2' :: RewriteD testThing2' = id2' (id2' RDUnit) {-# INLINE[1] id1' #-} {-# INLINE[1] id2' #-} id1' :: RewriteD -> RewriteD id2' :: RewriteD -> RewriteD id1' a = RDUnit id2' a = RDUnit

解决方案

(several edits made throughout post with updated information)

In your output, notice the lines Rule fired: Class op id2. These are rules automatically created by GHC for type class instances. This rule is firing first, so your own rule never gets a chance to match. If you compile with "-ddump-simpl-iterations", you can check that the Class op rule fires in the first phase, after which your "to1" rule will never match.

Here's a bit of a workaround. First comment out testThing1, testThing1', and testThing2' so only testThing2 is compiled. This is the only function where "rewrite/to1" can fire, so it isolates the test case you're looking at. Next add another rule of the form:

"rewrite/to_id2'" forall a. id2 a = id2' a

and you'll see this output:

$ ghc -c foo.hs Rule fired: rewrite/to_id2' Rule fired: rewrite/to_id2' Rule fired: rewrite/to1' Rule fired: rewrite/ez

The new rule is now firing instead of the class op, which allows rewrite/to1' to simplify the expression. Interestingly, it doesn't matter if the new rule appears above or below rewrite/to1 in the list of RULES.

I don't know why your id2 (id2 a) rule isn't matching whereas id2 a does. It looks like it should match (according to -dverbose-core2core), but it isn't. I still suspect a GHC precedence bug of some type, although I also see the same behavior with ghc-7.4.1 so it isn't 4397.

更多推荐

重写规则不会触发匹配多个实例方法的规则

本文发布于:2023-11-16 18:20:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1606684.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:规则   多个   重写   实例   方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!