Haskell 重写规则和函数组合

标签 haskell rules ghc function-composition

为什么 haskell 需要多个重写规则,具体取决于函数组合技术和长度?有没有办法避免这种情况?

例如,给定以下代码...

{-# RULES
"f/f" forall a. f ( f a ) = 4*a
  #-}
f a = 2 * a

这适用于
test1 = f ( f 1 )

但是我们需要为
test2 = f . f $ 1


test3 = f $ f 1

给我们留下以下规则
{-# 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
   #-}

但是,当我们将它们串在一起或使用其他形式的组合时,规则不会触发。
test4 = f . f . f $ 1
test5 = f $ f $ f $ 1
test6 = f $ 1

为什么是这样?我是否必须为每个可能的实现编写重写规则?

最佳答案

在许多情况下,该规则不会触发,因为非常简单的函数 f在规则有机会触发之前内联。如果你延迟内联,

{-# INLINE [1] f #-}

规则
{-# RULES "f/f" forall a. f (f a) = 4*a #-}

应该针对所有这些情况触发(在此处使用 7.2.2 和 7.4.1)。

原因是规则匹配器并不过分复杂,它只匹配具有规则语法形式的表达式(不完全正确,规则体也经过了一些规范化)。表达式 f $ f 3f . f $ 4不匹配规则的句法形式。为了匹配规则,必须进行一些重写,($)(.)必须在规则匹配表达式之前内联。但是如果你不阻止f从在简化器的第一阶段内联,它在与 ($) 相同的运行中被其主体替换和 (.)是内联的,所以在下一次迭代中,简化器看不到 f不再,它只看到 2*(2*x) ,不符合规则。

关于Haskell 重写规则和函数组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9253650/

相关文章:

haskell - 在haskell中故意定义无限类型

firebase - 如何配置 Firebase 项目的规则以确保安全?

java - 我应该使用报告框架吗?

tomcat - 我的 Tomcat 重写规则不起作用,我不知道为什么

haskell - 在 where 子句中进行类型推断

haskell - 我应该首先尝试学习哪些 GHC 类型系统扩展?

haskell - 构建相同的镜头

haskell - 修复 ghc-pkg 检查指出的问题

haskell : can only load one file at a time via :load

graphics - Haskell 像素绘图库 Linux