2011-05-17 28 views
6

Encuentro que rara vez me encuentro con situaciones en las que necesito usar la cláusula where. Sin embargo, sí encuentro que lo he usado muy ocasionalmente en el pasado. ¿Cuándo se usa la cláusula where (es decir, en qué situaciones se usa)? ¿Bajo qué circunstancias debo usarlo?donde la cláusula `where` es útil en Haskell

+3

Use 'WHERE' en su caso. – Tarrasch

+2

puede encontrar información útil en esta pregunta relacionada: [where vs. let] (http://stackoverflow.com/questions/4362328/haskell-where-vs-let) –

+0

gracias @ Thies Heidecke que ni siquiera vino ¡arriba! – maclunian

Respuesta

10

Hay dos excelentes respuestas a esta pregunta disponibles en el Haskell Wiki así:

http://haskell.org/haskellwiki/Declaration_vs._expression_style http://haskell.org/haskellwiki/Let_vs._Where

Ambos se utilizan para crear las definiciones locales que tal vez hacen uso de valores pasados ​​en el ámbito de su función adjunta, y ciertamente no están disponibles fuera del contexto de la función adjunta. Promueven la reutilización del código y minimizan la duplicación. Dados fix y lambda, ambos se pueden eliminar por completo. En general, uso cláusulas where siempre que sea posible, y solo uso cláusulas let para definiciones dentro de un bloque lambda o case, o en notación do, al hacer uso de valores extraídos a través de <- en líneas anteriores. En general, creo que el estilo declarativo es ahora mucho más predominante que el estilo de expresión en el código Haskell moderno idiomático.

1

Es sobre todo una cuestión de estilo. Incluso si no son exactamente equivalentes, no es muy frecuente que deba usar uno u otro. En cambio, depende de usted y de lo que piense que se ve mejor.

0

Mi regla de oro: si está definiendo algo en el nivel superior de una función, use "where". Si está definiendo una función auxiliar que tiene múltiples cláusulas, definitivamente use "where". En cualquier otro lugar, ¡solo elige uno!

+0

¿Quería usar "let" en uno de los lugares donde dice "where"? –

+0

No, tiendo a usar "donde" mucho :) –

3

Un ejemplo concreto donde lo he encontrado importante: una función que devuelve una matriz definida recursivamente.

lucas :: (Integral a) => a -> Array a 
lucas n = a where 
      a = array (0,n) ((0,2):(1,1):[(i,a!!(i-1) + a!!(i-2)) | i<-[1..n])]) 

Para los números Lucas 1 al n (Fibonacci habría sido sólo demasiado evidente = P)

El punto importante es que sin la cláusula where la matriz no tendría un nombre desde el interior del función del cuerpo y no podrías definir recursivamente.

0

En mi experiencia, where es más legible que let, porque a menudo se lee inquietantemente similar al inglés. Por ejemplo:

myFun x = aCoefficient * (10 ** anExponent) 
      where aCoefficient = 100 - x 
       anExponent = x - 2 

En Inglés, describiría esto como "myfun de X es un veces coeficiente (10 a un exponente), donde el coeficiente es 100 menos x, y el exponente es x menos 2 "

0

Dos ventajas estilísticas de la utilización de where:

  • se coloca el valor de la cosa que está definiendo cerca de su nombre (y tipo).

    func x = part1 . part2 (something x) 
        where part1 = ... 
         part2 = ... 
    

    en lugar de

    func x = let part1 = 
          part2 = 
         in part1 . part2 (something x) 
    
  • Se anima a escribir código que puede ser leído "estilo de periódico", donde lo importante es lo primero, y todos los detalles vienen después.De esa forma, puede dejar de leer cada vez que sienta que no necesita saber el resto de los detalles.

    func x = highlevel1 . highlevel2 (x + 42) 
        where highlevel1 = medium (...) 
         highlevel2 = medium (...) 
    
         medium = ... 
    

sobre todo lo uso let cuando los propios enlaces son más interesante que la expresión, y que son cortos. Por ejemplo, cuando la unión es sólo para hacer una comparación de patrones:

func x = let (MyData y _ _) = something in y 

Esto se ve mejor en mi opinión que

func x = y 
    where (MyData y _ _) = something 
Cuestiones relacionadas