问题
I create a lot of temporary variables in Haskell:
main = do
let nums'' = [1..10]
let nums' = a . bunch . of_ . functions $ nums''
let nums = another . bunch . of_ . functions $ nums'
print nums
That is, I don't want to write a long chain of functions like so:
let nums = another . bunch . of_ . functions . a . bunch . of_ . functions $ [1..10]
Because it becomes unreadable to me, so I try to group the functions according to what they do. In the process I end up creating a bunch of ugly temporary variables like nums''
and nums'
(I could give them more meaningful names, but the point still stands...every new line means a new variable).
This is a case where a shadowed variable would result in cleaner code. I'd like to do something like:
let nums = [1..10]
nums = a . bunch . of_ . functions $ nums
nums = another . bunch . of_ . functions $ nums
I.e. exactly the same as above but without the temporary variables. Is there any way to do this in Haskell? Maybe the whole thing could be wrapped in a "transaction":
atomically $ do
(...this code...)
return nums
Something that would let Haskell know that the code in this section contains shadowed variables, and it should only worry about the end result. Is this possible?
回答1:
This style is very common:
let nums = another
. bunch
. of_
. functions
. a
. bunch
. of_
. functions
$ [1..10]
It clearly delineates the code; while .
serves the place of the temporary variable name.
And it avoids the dangerous issues that can happen when you start shadowing variable names -- accidentally referring to the wrong x
will get you into trouble sooner or later.
回答2:
Here's a suggestion nobody else has given which I use from time to time: you may like naming your functions rather than naming your values! For example, perhaps you might write:
let runningSum = a . bunch . of_ . functions
weight = another . bunch . of_ . functions
in weight . runningSum $ [1..10]
回答3:
Since your names (nums
, nums'
, nums''
, ...) convey no information about the grouping, you can just use line breaks to group the functionality and communicate the same thing:
main =
let nums = a . bunch . of_ . functions
. another . bunch . of_ . functions
$ [1..10]
in print nums
However, I would suggest that instead of doing this, you give the subcomputations names which do convey information, eg. normalizedNums
, average
, etc. Then there is no ugly shadowing issue because you are using distinct names.
回答4:
If you absolutely must, it's possible, but not idiomatic. Use what Don or luqui suggest instead.
main = do
nums <- return [1..10]
nums <- return $ a . bunch . of_ . functions $ nums
nums <- return $ another . bunch . of_ . functions $ nums
print nums
If you're not in a monad, you can always start a new do block in the identity monad.
来源:https://stackoverflow.com/questions/10642430/avoid-temporary-variables-by-using-name-shadowing