15

我正在看教程http://haskell.org/haskellwiki/How_to_write_a_Haskell_program

import System.Environment

main :: IO ()
main = getArgs >>= print . haqify . head

haqify s = "Haq! " ++ s

在 HLint 下运行此程序时,会出现以下错误;

./Haq.hs:11:1: Warning: Eta reduce
Found:
  haqify s = "Haq! " ++ s
Why not:
  haqify = ("Haq! " ++ )

有人可以阐明“Eta Reduce”在这种情况下的确切含义吗?

4

3 回答 3

22

只要 没有. \x -> f x_ f_fx

要检查它们是否相同,请将它们应用于某个值y

(\x -> f x) y === f' y -- (where f' is obtained from f by substituting all x's by y)
              === f y  -- since f has no free occurrences of x

您对 的定义haqify被视为\s -> "Haq! " ++ s,这是 . 的语法糖\s -> (++) "Haq! " s。反过来,可以将其 eta 简化为(++) "Haq! ",或等效地,使用运算符的节表示法 ,("Haq! " ++)

于 2011-04-26T17:23:14.153 回答
16

嗯,eta 归约是(一种)制作无点函数的方法,通常意味着您可以删除函数的最后一个参数,如果它出现在表达式两侧的末尾。

f :: Int -> Int
g :: Int -> Int -> Int
f s = g 3 s 

可以转换为

f = g 3

但是,在这种情况下,它会稍微复杂一些,因为(++)rhs 上有双参数运算符的语法糖,即 type [a] -> [a] -> [a]。但是,您可以将其转换为更标准的函数:

 haqify ::  [Char] -> [Char]
 haqify = (++) "Haq! "

因为(++)是运算符,所以还有其他可能:

haqify = ("Haq! " ++ )

也就是说,括号将其转换为适用于其参数的单参数函数。"Haq!" ++

于 2011-04-26T17:26:07.497 回答
13

根据 lambda 演算,我们将 eta 转换定义为等式:

 \x -> M x == M      -- if x is not free in M.

参见 Barendregt,HP The Lambda Calculus: Its Syntax and Semantics,1984 年。


在 Haskell 上下文中,请参阅Haskell wiki 上的定义

n eta 转换(也写为 η 转换)是在函数上添加或删除抽象。例如,以下两个值在 η 转换下是等价的:

\x -> abs x

abs

从第一个转换为第二个将构成 eta 缩减,从第二个转换为第一个将是一个 eta 抽象。术语“eta 转换”可以指任一方向的过程。广泛使用 η 约简可以导致无点编程。它通常也用于某些编译时优化。

于 2011-04-26T17:26:49.693 回答