Haskell 重写与多个实例方法匹配的规则不触发的规则
就我所知,我不认为id1和id2来自类型类,而id1'和id2'不来自类型类会有任何区别。我正在使用最新的Haskell平台运行“ghc重写”(ghc 7.0.4版和现在的7.4.1版),我希望1也会启动Haskell 重写与多个实例方法匹配的规则不触发的规则,haskell,Haskell,就我所知,我不认为id1和id2来自类型类,而id1'和id2'不来自类型类会有任何区别。我正在使用最新的Haskell平台运行“ghc重写”(ghc 7.0.4版和现在的7.4.1版),我希望1也会启动 $ ghc Rewrite [1 of 1] Compiling RewriteProblems ( Rewrite.hs, Rewrite.o ) Rule fired: rewrite/ez' Rule fired: rewrite/to1' Rule fired: rewrite/ez
$ 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
例如:
{-# 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
(在整个帖子中进行了多次编辑,更新了信息)
请注意输出中的行规则激发:Class op id2
。这些是GHC为类型类实例自动创建的规则。这条规则是先开火,所以你自己的规则永远不会有机会匹配。如果使用“-ddump siml iterations”进行编译,则可以检查类op规则是否在第一阶段触发,之后的“to1”规则将永远不匹配
这里有一点变通方法。首先注释掉testThing1
,testThing1'
和testThing2'
,因此只编译testThing2
。这是唯一可以触发“rewrite/to1”的函数,因此它隔离了您正在查看的测试用例。接下来,添加表单的另一条规则:
"rewrite/to_id2'" forall a. id2 a = id2' a
您将看到以下输出:
$ ghc -c foo.hs
Rule fired: rewrite/to_id2'
Rule fired: rewrite/to_id2'
Rule fired: rewrite/to1'
Rule fired: rewrite/ez
新规则现在触发,而不是op类,它允许rewrite/to1'
简化表达式。有趣的是,新规则是否出现在规则列表中rewrite/to1
的上方或下方并不重要
我不知道为什么您的
id2(id2 a)
规则不匹配,而id2 a
规则匹配。它看起来应该匹配(根据-dverbose-core2core),但事实并非如此。我仍然怀疑某种类型的GHC优先错误,尽管我也看到GHC-7.4.1的相同行为,但事实并非如此。我刚刚安装了GHC的最新版本——7.4.1版,现在得到的输出与以前相同。另外,是的,我意识到这些规则对输出没有影响——我只是做了这个测试用例来隔离我在一个更复杂的例子中遇到的问题。而且,我相信优先权在这里是正确的。。。只要看一下输出,我的所有规则似乎都在出现之前就已经尝试过了。您如何确定您的规则是否已经尝试过?我知道没有办法让GHC显示未应用的规则,或者在多个匹配的情况下使用哪个规则。您所能做的最好的事情就是检查实际触发的是什么,在本例中是类op规则。如果您更改程序,使实例方法返回类似错误的内容,即与RDUnit
不同的内容,则重写规则应留给您,优化器在testThing2
示例中为您留下错误值。我认为这个示例程序只是被简化了一点,无法最清楚地说明问题。我不知道,但我可以看到GHC已经取消了我的所有规则,除了这篇文章针对的特定规则,虽然我只能模糊地说我认为规则正在尝试,但我也没有迹象表明它没有尝试,任何一个类op规则告诉我除了我的规则没有被触发和我的方法没有短路之外,什么都没有,我已经观察到了。另外,如果是顺序问题和您指定的bug,我希望更新版本的GHC能够解决这个问题…Anthony,我制作这个示例是为了演示规则将在简单规则与复杂规则以及实例与非实例方法的4种排列中的3种中触发——实际值仅用于检查所有类型。约翰L,我现在才注意到你更新了答案。我有点抗拒使用那个黑客,但它应该能工作。谢谢