我有一个重写规则,如下所示:
{-# RULES
"modify/fusedModify" forall f g key book. modify key f (modify key g book) = fusedModify key f g book
#-}
以下功能触发:
pb :: PersonB
pb = ...
fusionB' :: PersonB
fusionB' =
let l x = (modify #name ('c':) (modify #name ('a':) x))
in l pb
然而,没有让(并且可能是抽象?)它不会触发:
fusionB :: PersonB
fusionB = modify #name ('c':) (modify #name ('a':) pb)
如果它采用了其他方式 - 也就是说,如果let-abstracted版本没有导致触发,但是fusionB
做了 - 我想我明白了。可能在特定情况下,fusedModify
具有正确的类型签名,但在一般(更多态)情况下,它不具有。但为什么在这个世界上我看到了这个?
对于它的价值,fusedModify
的定义是here,而fusionB
和fusionB'
的文件是here。我已经尝试unsafeCoercing
类型均衡来获得两个签名匹配(实际上,尽管GHC没有意识到它,它们总是匹配),但不知何故这也无济于事。
编辑:我或许应该提到我正在使用GHC 8.0.1。