使用名称阴影避免临时变量

时间:2012-05-17 19:40:18

标签: haskell syntax composition

我在Haskell中创建了很多临时变量:

main = do
    let nums'' = [1..10]
    let nums' = a . bunch . of_ . functions $ nums''
    let nums = another . bunch . of_ . functions $ nums'
    print nums

也就是说,我不想像这样编写一长串函数:

let nums = another . bunch . of_ . functions . a . bunch . of_ . functions $ [1..10]

因为它对我来说变得不可读,所以我尝试根据他们的行为对功能进行分组。在这个过程中,我最终创建了一堆丑陋的临时变量,如nums''nums'(我可以给它们更有意义的名称,但重点仍然是......每一个新行都意味着一个新的变量) 。 这是一个阴影变量会导致更清晰的代码的情况。我想做点什么:

let nums = [1..10]
nums = a . bunch . of_ . functions $ nums
nums = another . bunch . of_ . functions $ nums

即。与上面完全相同但没有临时变量。在Haskell有什么办法吗?也许整个事情可以包含在“交易”中:

atomically $ do
  (...this code...)
  return nums

让Haskell知道本节中的代码包含阴影变量的东西,它应该只关心最终结果。这可能吗?

4 个答案:

答案 0 :(得分:12)

这种风格很常见:

let nums = another
         . bunch
         . of_
         . functions
         . a
         . bunch
         . of_
         . functions
         $ [1..10]

它清楚地描述了代码;而.用作临时变量名称的位置。

它避免了当你开始隐藏变量名时可能发生的危险问题 - 不小心引用错误的x迟早会让你陷入困境。

答案 1 :(得分:9)

以下是其他人没有给出的建议:我可能会不时地命名您的功能而不是命名您的值!例如,也许您可​​以写:

let runningSum = a . bunch . of_ . functions
    weight     = another . bunch . of_ . functions
in weight . runningSum $ [1..10]

答案 2 :(得分:6)

由于您的姓名(numsnums'nums'',...)未传达有关分组的信息,因此您可以使用换行符对功能进行分组并进行通信事情:

main =
    let nums = a . bunch . of_ . functions
             . another . bunch . of_ . functions
             $ [1..10]
    in print nums

但是,我建议您不要这样做,而是给出传达信息的子计算名称,例如。 normalizedNumsaverage等。然后没有丑陋的阴影问题,因为您使用的是不同的名称。

答案 3 :(得分:5)

如果你绝对必须,这是可能的,但不是惯用的。请使用Don或luqui建议的内容。

main = do
    nums <- return [1..10]
    nums <- return $ a . bunch . of_ . functions $ nums
    nums <- return $ another . bunch . of_ . functions $ nums
    print nums

如果你不在monad中,你总是可以在身份monad中启动一个新的do块。