如何避免两次使用相同参数调用相同的函数?

Fra*_*tal 2 haskell

我有一段这样的代码

if (result-of-a-func-call) > 0
    then (result-of-a-func-call)
    else -2
Run Code Online (Sandbox Code Playgroud)

有没有办法避免第二次调用相同的函数(使用相同的参数)?在命令式语言中,我们可以做类似的事情

if((result=func-call())>0)
    result
else
    -2
Run Code Online (Sandbox Code Playgroud)

bhe*_*ilr 7

您可以使用let或执行此操作where:

f x =
    let y = g x
    in if y > 0 then y else -2
Run Code Online (Sandbox Code Playgroud)

要么

f x = if y > 0 then y else -2
    where y = g x
Run Code Online (Sandbox Code Playgroud)

这里两者之间存在细微差别,要记住的最大区别是where可以用来定义在函数调用之间不会改变的值,编译器只会定义一次值,而let每个都会定义一个本地值.调用函数的时间,例如

f x = g x
    where g y = y * y + 1
Run Code Online (Sandbox Code Playgroud)

f x =
    let g y = y * y + 1
    in g x
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,g仅定义一次,因为它不依赖于任何f参数(x),而在第二个示例g中,每次f调用时都重新定义.有理由希望这两种方法都超出了这个答案的范围.

  • @ mb14名称`y`最初将绑定到`gx`的thunk.一旦thunk被强制通过`y> 0`,名称`y`将被绑定到`gx`的正常形式结果.您可以使用`:sprint`命令在GHCi中验证这一点:`let gx = x + 1`; `let y = g(1 :: Int)`(类型签名需要防止`y :: Num a => a`); `:sprint y`打印出`y = _`; `y> 0`打印出`True`; `:sprint y`打印出`y = 2`.如果你真的是偏执狂,请使用`Debug.Trace.trace`,但我保证Haskell的懒惰不会导致`g`被调用两次. (2认同)