【问题标题】:Seemingly legal Eta reduction causing issues看似合法的 Eta 减少导致问题
【发布时间】:2018-10-04 17:02:23
【问题描述】:

我正在尝试 η-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
  ...

这按预期工作。看来我应该能够完全 η-reduce 以获得无点函数

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

是否有可能进一步减少 η-reduce,如果可以,如何?

【问题讨论】:

  • \combiner -> flip $ foldMap combiner\combiner -> ($) flip (foldMap combiner),所以你可以看到,eta 不适用:RHS 上的最后一个参数是 foldMap combiner,而不是 combiner

标签: haskell pointfree


【解决方案1】:

引发错误,因为g b = f $ a b 不等于g = f $ a

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

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

第二种情况:

  • 将函数f应用于a

因此,您只是 flip foldMap 函数,但实际上想要在 flip foldMap 函数之后combiner 传递给它。这使我们得出结论,您实际上想要该组合物,即。 e. .函数:

foldr = flip . foldMap where
  ...

【讨论】:

  • 这个答案是完全正确的 (+1),但让我补充一点,我认为 flip . foldMap 的可读性不如原始代码。事实上,flip . f 不会立即触发“哦,它是 f,第二个和第三个参数翻转了”,就像原始代码一样。
猜你喜欢
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 2011-12-29
  • 2019-10-18
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多