Eu sou novo em Haskell e estou muito confuso com Where vs. Let . Ambos parecem fornecer um propósito semelhante. Eu li algumas comparações entre Where vs. Let, mas estou tendo problemas para discernir quando usar cada uma. Alguém poderia fornecer algum contexto ou talvez alguns exemplos que demonstrem quando usar um em vez do outro?
Onde vs. Let
Uma
where
cláusula só pode ser definida no nível da definição de uma função. Normalmente, isso é idêntico ao escopo dalet
definição. A única diferença é quando os guardas estão sendo usados . O escopo dawhere
cláusula se estende a todos os guardas. Em contraste, o escopo de umalet
expressão é apenas a cláusula de função atual e guarda, se houver.
Folha de referências de Haskell
The Haskell Wiki é muito detalhado e fornece vários casos, mas usa exemplos hipotéticos. Acho suas explicações muito breves para um iniciante.
Vantagens do Let :
f :: State s a
f = State $ \x -> y
where y = ... x ...
não funcionará, porque onde se refere ao padrão correspondente f =, onde nenhum x está no escopo. Em contraste, se você tivesse começado com let, não teria problemas.
Haskell Wiki sobre as vantagens do Let
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Vantagens de onde :
f x
| cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
where
a = w x
f x
= let a = w x
in case () of
_ | cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
O wiki Haskell menciona que a cláusula Where é declarativa, enquanto a expressão Let é expressiva. Além do estilo, como eles atuam de forma diferente?
Declaration style | Expression-style
--------------------------------------+---------------------------------------------
where clause | let expression
arguments LHS: f x = x*x | Lambda abstraction: f = \x -> x*x
Pattern matching: f [] = 0 | case expression: f xs = case xs of [] -> 0
Guards: f [x] | x>0 = 'a' | if expression: f [x] = if x>0 then 'a' else ...
- No primeiro exemplo, por que o escopo Let está dentro, mas onde não está?
- É possível aplicar Onde ao primeiro exemplo?
- Alguns podem aplicar isso a exemplos reais onde as variáveis representam expressões reais?
- Existe uma regra geral a ser seguida quando usar cada um?
Atualizar
Para aqueles que vêm por este tópico mais tarde, encontrei a melhor explicação a ser encontrada aqui: " Uma introdução gentil a Haskell ".
Let Expressions.
As expressões let de Haskell são úteis sempre que um conjunto aninhado de ligações é necessário. Como um exemplo simples, considere:
let y = a*b f x = (x+y)/y in f c + f d
O conjunto de associações criadas por uma expressão let é mutuamente recursiva e as associações de padrão são tratadas como padrões preguiçosos (ou seja, carregam um ~ implícito). Os únicos tipos de declarações permitidas são assinaturas de tipo, associações de função e associações de padrão.
Onde Cláusulas.
Às vezes, é conveniente definir o escopo das ligações em várias equações protegidas, o que requer uma cláusula where:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
Observe que isso não pode ser feito com uma expressão let, que abrange apenas a expressão que ela inclui. Uma cláusula where só é permitida no nível superior de um conjunto de equações ou expressão case. As mesmas propriedades e restrições sobre ligações em expressões let se aplicam àquelas em cláusulas where. Essas duas formas de escopo aninhado parecem muito semelhantes, mas lembre-se de que uma expressão let é uma expressão, enquanto uma cláusula where não é - ela é parte da sintaxe de declarações de função e expressões case.
f = body where x = xbody; y = ybody ...
significaf = let x = xbody; y = ybody ... in body
case .... of ... where
expressão de alguma forma? Eu não tenho certeza sobre isso.
let
ewhere
quando comecei a aprender Haskell. Acho que a melhor maneira de entender isso é perceber que há muito pouca diferença entre os dois e, portanto, nada com que se preocupar. O significado dewhere
dado em termos delet
uma transformação mecânica muito simples. Veja haskell.org/onlinereport/decls.html#sect4.4.3.2 Essa transformação existe apenas para conveniência de notação, na verdade.