【问题标题】:Why is this an invalid eta conversion?为什么这是无效的 eta 转换?
【发布时间】:2026-02-13 00:15:01
【问题描述】:

我正在研究 Haskell 中的一个非常基本的问题。我试图计算字符串中小写字母的数量。我的解决方案是这样的

import Data.Char

lowercaseCount :: String -> Int
lowercaseCount x = length $ filter isLower x

我正在查看lowercaseCount 的实际实现,发现它似乎应该能够进行 eta 减少。我试过这个

lowercaseCount = length $ filter isLower

但是 GHC 对我大喊大叫

无法匹配预期类型[Char] -> Int 与实际类型Int

我想知道为什么这个 eta 减少是非法的,以及是否有办法使这个函数能够成为一个 eta 减少的形式。

【问题讨论】:

  • @Carcigenicate 是的。就是这样。我很尴尬。对此感到抱歉。

标签: haskell lambda-calculus


【解决方案1】:
lowercaseCount x = length $ filter isLower x

意思

lowercaseCount x = length (filter isLower x)    -- (1)

同时

lowercaseCount = length $ filter isLower

意思

lowercaseCount = length (filter isLower)

经过eta-expansion变成

lowercaseCount x = length (filter isLower) x  -- (2)

现在应该很明显 (1) 和 (2) 不等价。后者将两个参数传递给length,触发类型错误。

【讨论】:

  • 这是一个很好的分解方法。
【解决方案2】:

您需要使用函数组合而不是应用程序。因为您只是部分应用了filter,所以它会产生一个函数。

你需要将它组合成length而不是应用它:

lowercaseCount = length . filter isLower

【讨论】:

  • 完美答案!接受将在 4 分钟后到来。