6

我在 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''and 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

4 回答 4

14

这种风格很常见:

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

它清楚地描述了代码;while.代替临时变量名。

并且它避免了当你开始隐藏变量名时可能发生的危险问题——不小心引用错误x迟早会给你带来麻烦。

于 2012-05-17T19:43:51.410 回答
10

这是我不时使用的其他人没有给出的建议:您可能喜欢命名您的函数而不是命名您的值!例如,也许你可以写:

let runningSum = a . bunch . of_ . functions
    weight     = another . bunch . of_ . functions
in weight . runningSum $ [1..10]
于 2012-05-17T21:49:02.280 回答
6

如果你绝对必须,这是可能的,但不是惯用的。改用 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 中,你总是可以在 identity monad 中启动一个新的 do 块。

于 2012-05-17T20:25:53.687 回答
6

由于您的名称 ( nums, nums', nums'', ...) 没有传达有关分组的信息,因此您可以使用换行符对功能进行分组并传达相同的信息:

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

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

于 2012-05-17T20:44:15.943 回答