Toy*_*rii 9 haskell rules ghc function-composition
为什么haskell需要多个重写规则,具体取决于函数组合技术和长度?有办法避免这种情况吗?
例如,给出以下代码......
{-# RULES
"f/f" forall a. f ( f a ) = 4*a
#-}
f a = 2 * a
Run Code Online (Sandbox Code Playgroud)
这适用于
test1 = f ( f 1 )
Run Code Online (Sandbox Code Playgroud)
但是我们需要添加规则
test2 = f . f $ 1
Run Code Online (Sandbox Code Playgroud)
和
test3 = f $ f 1
Run Code Online (Sandbox Code Playgroud)
给我们留下以下规则
{-# RULES
"f/f1" forall a. f ( f a ) = 4 * a
"f/f2" forall a. f . f $ a = 4 * a
"f/f3" forall a. f $ f $ a = 4 * a
#-}
Run Code Online (Sandbox Code Playgroud)
但是,当我们将这些组合在一起或使用其他形式的组合时,规则就不会触发.
test4 = f . f . f $ 1
test5 = f $ f $ f $ 1
test6 = f $ 1
Run Code Online (Sandbox Code Playgroud)
为什么是这样?我是否必须为每个可能的实现编写重写规则?
Dan*_*her 13
在许多情况下,规则不会触发,因为f在规则有机会触发之前,内联函数非常简单.如果延迟内联,
{-# INLINE [1] f #-}
Run Code Online (Sandbox Code Playgroud)
规则
{-# RULES "f/f" forall a. f (f a) = 4*a #-}
Run Code Online (Sandbox Code Playgroud)
应解雇所有这些案件(在这里与7.2.2和7.4.1一起工作).
原因是规则匹配器不是过于复杂,它只匹配具有规则的句法形式的表达式(不完全正确,规则体也经历了一些规范化).表达式f $ f 3或f . f $ 4与规则的语法形式不匹配.要匹配规则,必须进行一些重写,($)并且(.)必须在规则与表达式匹配之前进行内联.但是,如果你不阻止f从简化器的第一阶段被内联,它就会被它的身体取代了相同的运行方式($)和(.)内联,所以在接下来的迭代中,简化器看不到f了,它只能看到2*(2*x),这与规则不符.