2012-05-17 9 views
6

puedo crear una gran cantidad de variables temporales en Haskell:variables temporales utilizando el nombre de sombra

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

Es decir, no quiero escribir una cadena larga de las funciones de este modo:

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

Porque se vuelve ilegible para mí, así que intento agrupar las funciones de acuerdo con lo que hacen. En el proceso, termino creando un montón de feas variables temporales como nums'' y nums' (podría darles nombres más significativos, pero el punto sigue en pie ... cada nueva línea significa una nueva variable). Este es un caso donde una variable sombreada daría como resultado un código más limpio. Me gustaría hacer algo como:

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

I.e. exactamente lo mismo que arriba pero sin las variables temporales. ¿Hay alguna forma de hacer esto en Haskell? Tal vez todo el asunto podría ser envuelto en una "transacción":

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

Algo que permitiría a Haskell sabe que el código de esta sección contiene variables ocultas, y sólo debe preocuparse por el resultado final. es posible?

+0

También es posible usar la mónada Estado si quiere pasar un valor a lo largo y sin mutación aún sin crear un montón de nombres – amindfv

+3

podría argumentar que (a) si tiene sentido nombres para dar los pasos intermedios, no hay problema; y (b) si no tiene nombres significativos para dar los pasos intermedios, entonces no hay beneficio en dividirlos. Y de (a) y (b) podemos concluir que no hay problema. Depende de si acepta las instalaciones, por supuesto. –

+4

No estoy de acuerdo con que reutilizar el mismo nombre para diferentes propósitos necesariamente lo haga más legible. Ahora el lector tiene que descubrir a qué variable se refiere cada incidente. – augustss

Respuesta

11

Este estilo es muy común:

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

Se delimita claramente el código; mientras que . sirve el lugar del nombre de la variable temporal.

Y evita los problemas peligrosos que pueden ocurrir cuando comienza a sombrear los nombres de las variables: si accidentalmente se refiere al x incorrecto, tarde o temprano tendrá problemas.

4

Si es absolutamente necesario, es posible, pero no idiomático. Usa lo que Don o luqui sugieren en su lugar.

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

Si no está en una mónada, siempre puede comenzar un nuevo bloque de ejecución en la mónada de identidad.

6

Desde sus nombres (nums, nums', nums'', ...) transmitir ninguna información sobre la agrupación, sólo puede utilizar saltos de línea para la funcionalidad de grupo y comunicar la misma cosa:

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

Sin embargo, Sugeriría que, en lugar de hacer esto, proporcione los nombres de subcomputación que hacen transmiten información, p. Ej. normalizedNums, average, etc. Entonces no hay un problema de sombreado feo porque está usando nombres distintos.

7

Aquí hay una sugerencia que nadie más ha dado que uso de vez en cuando: ¡puede que le guste nombrar sus funciones en lugar de nombrar sus valores!Por ejemplo, tal vez usted podría escribir:

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