【问题标题】:How to convert this let/where function to a Lambda in Haskell如何将此 let/where 函数转换为 Haskell 中的 Lambda
【发布时间】:2026-01-14 05:05:01
【问题描述】:

如何在 Haskell 中将此 let/where 函数转换为 lambda?

让语句形式:

calc x =    let ad5 x = x + 5
                sqr x = x * x
                dbl x = x * 2
            in
                ad5 . sqr . dbl $ x

凡申报表:

calc x = ad5 . sqr . dbl $ x
  where
        ad5 x = x + 5
        sqr x = x * x
        dbl x = x * 2

Lambda 形式?可能类似于 Get Prog 中的这个示例,其中首先声明变量,然后在底部定义:

sumSqrOrSqrSum4 x y =   (\sumSqr sqrSum ->
                        if sumSqr > sqrSum
                        then sumSqr
                        else sqrSum) (x^2 + y^2) ((x + y)^2)

【问题讨论】:

  • 如果您需要 lambda 用于内联使用,那么 (\x -> ((x+5)*(x+5))*2) 4 可能会导致 162。它并不优雅,但很短并且可以工作。

标签: haskell


【解决方案1】:

想法是这个let 表达式:

let x = y in z

和这个 lambda 完全一样:

(\x -> z) y

其中y 被用作参数,因此绑定到x

在你的情况下,这将导致:

calc x = (\ad5 sqr dbl -> (ad5 . sqr . dbl $ x))
         (\x -> x + 5)
         (\x -> x * x)
         (\x -> x * 2)

当然,除了这个练习之外,很少有人会真正这样写:)

【讨论】:

  • 谢谢布拉德!我实际上之前尝试过,但没有在以下定义中使用反斜杠。问:在 Get Prog 示例中,他们如何在没有反斜杠的情况下逃脱?
  • @bevo009 我猜在 Get Prog 中您的 where 没有定义函数(即 sumSqrsqrSum 不是函数)。相反,ad5sqrdbl 被定义为 where 中的函数,因此它们成为 lambda。
  • @chi 有道理,所以变量/值不需要反斜杠,但函数需要。干杯!。
  • 为了完整起见,我将添加它,这是布拉德答案的反向版本,使用 & 运算符(实际上是我开始使用的)``` import Data.Function calc x = (\ ad5 sqr dbl -> (x & dbl & sqr & ad5)) (\x -> x + 5) (\x -> x * x) (\x -> x * 2) ``` ...但是对于出于某种原因,我的标记很糟糕,代码都乱七八糟了,对不起!
  • 为了完整起见:“完全相同”仅在y 未提及x 时才成立,即它是非递归let
【解决方案2】:

对 lambda 的最简单直接的翻译是

calc = \x -> (x*2)*(x*2) + 5

虽然显然您可以使用基本数学来稍微简化该表达式。

【讨论】:

  • 感谢单行版本 :) 我展示的 Get Prog 示例如何,其中有命名变量?过去 2 天我一直坚持这一点
  • 恐怕我不知道 Get Prog 是什么。我实际上误读了您的最终代码 sn-p,但现在看到 @bradrn 的回答我同意他的看法,希望这能回答您的问题?我以为你只是想将 calc 翻译成 lambda 表达式。
  • 这一切都在帮助我,你的例子也是,谢谢队友!