看似合法的 Eta 减少导致问题

Seemingly legal Eta reduction causing issues

我正在尝试 η-reduce 函数

foldr :: (a -> b -> b) -> b -> BinaryTree a -> b
foldr combiner base tree = foldMap combiner tree base where
  foldMap = ...

foldMap :: (a -> b -> b) -> BinaryTree a -> b -> b

按预期工作。

我降低了 η

foldr combiner base tree = foldMap combiner tree base

foldr combiner = flip $ foldMap combiner where
  ...

这按预期工作。看来我应该能够完全减少 η 以获得 pointfree 函数

foldr = flip $ foldMap where
  ...

但是,这会导致编译错误

Couldn't match type ‘a -> b -> b’ with ‘BinaryTree t0’
Expected type: (a -> b -> b) -> b -> BinaryTree a -> b
  Actual type: BinaryTree t0 -> (t0 -> b -> b) -> b -> b

是否有可能进一步减少 η,如果可以,怎么做?

出现错误,因为 g b = f $ a b 不等同于 g = f $ a

在第一种情况下,您将获得以下评估序列:

  • 将函数 a 应用于 b(使用 b 作为参数调用 a
  • 将函数f应用于结果

第二种情况:

  • 将函数 f 应用到 a

因此,您只是 flip foldMap 函数,但实际上想要 flip foldMap 函数 after 传递combiner 就可以了。这使我们得出结论,您实际上想要组成,我。 e. . 函数:

foldr = flip . foldMap where
  ...